// Might throw.
  private SQLiteConnection tryAcquireNonPrimaryConnectionLocked(String sql, int connectionFlags) {
    // Try to acquire the next connection in the queue.
    SQLiteConnection connection;
    final int availableCount = mAvailableNonPrimaryConnections.size();
    if (availableCount > 1 && sql != null) {
      // If we have a choice, then prefer a connection that has the
      // prepared statement in its cache.
      for (int i = 0; i < availableCount; i++) {
        connection = mAvailableNonPrimaryConnections.get(i);
        if (connection.isPreparedStatementInCache(sql)) {
          mAvailableNonPrimaryConnections.remove(i);
          finishAcquireConnectionLocked(connection, connectionFlags); // might throw
          return connection;
        }
      }
    }
    if (availableCount > 0) {
      // Otherwise, just grab the next one.
      connection = mAvailableNonPrimaryConnections.remove(availableCount - 1);
      finishAcquireConnectionLocked(connection, connectionFlags); // might throw
      return connection;
    }

    // Expand the pool if needed.
    int openConnections = mAcquiredConnections.size();
    if (mAvailablePrimaryConnection != null) {
      openConnections += 1;
    }
    if (openConnections >= mMaxConnectionPoolSize) {
      return null;
    }
    connection = openConnectionLocked(mConfiguration, false /*primaryConnection*/); // might throw
    finishAcquireConnectionLocked(connection, connectionFlags); // might throw
    return connection;
  }
示例#2
0
  @SuppressWarnings("unchecked")
  public static <T> MethodCapturer<T> capture(T obj) {
    synchronized (s_cache) {
      MethodCapturer<T> capturer = (MethodCapturer<T>) s_cache.get(obj);
      if (capturer != null) {
        return capturer;
      }

      final MethodCapturer<T> capturerNew = new MethodCapturer<T>();

      Enhancer en = new Enhancer();
      en.setSuperclass(obj.getClass());
      en.setCallbacks(
          new Callback[] {
            new MethodInterceptor() {
              @Override
              public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3)
                  throws Throwable {
                capturerNew.setMethod(arg1);
                return null;
              }
            },
            new MethodInterceptor() {
              @Override
              public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3)
                  throws Throwable {
                return null;
              }
            }
          });
      en.setCallbackFilter(
          new CallbackFilter() {
            @Override
            public int accept(Method method) {
              if (method.getParameterTypes().length == 0 && method.getName().equals("finalize")) {
                return 1;
              }
              return 0;
            }
          });

      capturerNew.setInstance((T) en.create());

      // We expect MethodCapturer is only used for singleton objects here, so we only maintain a
      // limited cache
      // here
      if (s_cache.size() < CACHE_SIZE) {
        s_cache.put(obj, capturerNew);
      }

      return capturerNew;
    }
  }
  public static void main(String[] args) {

    WeakHashMap<String, String> map = new WeakHashMap<String, String>();
    // 测试数据
    // 常量池对象不会回收
    map.put("abc", "a");
    map.put("d", "tets");
    // gc运行已被回收
    map.put(new String(""), "d");

    // 通知回收
    System.gc();
    System.runFinalization();
    System.out.println(map.size());
  }
 // Can't throw.
 private void markAcquiredConnectionsLocked(AcquiredConnectionStatus status) {
   if (!mAcquiredConnections.isEmpty()) {
     ArrayList<SQLiteConnection> keysToUpdate =
         new ArrayList<SQLiteConnection>(mAcquiredConnections.size());
     for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry :
         mAcquiredConnections.entrySet()) {
       AcquiredConnectionStatus oldStatus = entry.getValue();
       if (status != oldStatus && oldStatus != AcquiredConnectionStatus.DISCARD) {
         keysToUpdate.add(entry.getKey());
       }
     }
     final int updateCount = keysToUpdate.size();
     for (int i = 0; i < updateCount; i++) {
       mAcquiredConnections.put(keysToUpdate.get(i), status);
     }
   }
 }
  private void dispose(boolean finalized) {
    if (mCloseGuard != null) {
      if (finalized) {
        mCloseGuard.warnIfOpen();
      }
      mCloseGuard.close();
    }

    if (!finalized) {
      // Close all connections.  We don't need (or want) to do this
      // when finalized because we don't know what state the connections
      // themselves will be in.  The finalizer is really just here for CloseGuard.
      // The connections will take care of themselves when their own finalizers run.
      synchronized (mLock) {
        throwIfClosedLocked();

        mIsOpen = false;

        closeAvailableConnectionsAndLogExceptionsLocked();

        final int pendingCount = mAcquiredConnections.size();
        if (pendingCount != 0) {
          Log.i(
              TAG,
              "The connection pool for "
                  + mConfiguration.label
                  + " has been closed but there are still "
                  + pendingCount
                  + " connections in use.  They will be closed "
                  + "as they are released back to the pool.");
        }

        wakeConnectionWaitersLocked();
      }
    }
  }
 @NotNull
 public Object[] getToExpand() {
   return myToExpand.keySet().toArray(new Object[myToExpand.size()]);
 }
 @NotNull
 public Object[] getToSelect() {
   return myToSelect.keySet().toArray(new Object[myToSelect.size()]);
 }