【发布时间】:2017-10-07 05:46:21
【问题描述】:
我正在研究GenericObjectPool,将Cipher 放入池中,以便可以重复使用。
GenericObjectPool<Cipher> pool;
CipherFactory factory = new CipherFactory();
this.pool = new GenericObjectPool<Cipher>(factory);
pool.setMaxTotal(10);
pool.setBlockWhenExhausted(true);
pool.setMaxWaitMillis(30 * 1000);
密码工厂
public class CipherFactory extends BasePooledObjectFactory<Cipher> {
private boolean running = false;
@Override
public Cipher create() throws Exception {
return Cipher.getInstance("DESede/CBC/NoPadding");
}
@Override
public PooledObject<Cipher> wrap(Cipher arg0) {
return new DefaultPooledObject<Cipher>(arg0);
}
@Override
public boolean validateObject(PooledObject<Cipher> p) {
//Ensures that the instance is safe to be returned by the pool
return true;
}
@Override
public void destroyObject(PooledObject<Cipher> p) {
//Destroys an instance no longer needed by the pool.
System.out.println("destroying");
}
@Override
public void activateObject(PooledObject<Cipher> p) throws Exception { //Reinitialize an instance to be returned by the pool
setRunning(true);
}
@Override
public void passivateObject(PooledObject<Cipher> p) throws Exception { // reset the object after the object returns to the pool
setRunning(false);
}
public void setRunning(boolean running) {
this.running = running;
}
//
}
这就是我在 Example 类中实现 ObjectPool 的方式
public Key a(byte[] afyte) throws Exception {
Cipher cipher = null;
cipher = pool.borrowObject(); //get the object from the pool
try {
System.out.println("****************** After borrow ****************");
printPool();
cipher.init(Cipher.DECRYPT_MODE, mkkey, algParamSpec);
byte[] de = cipher.doFinal(afyte);
SecretKey mk = new SecretKeySpec(de, "DESede");
return mk;
} catch (Exception e) {
pool.invalidateObject(cipher);
cipher = null;
} finally {
if (null != cipher) {
pool.returnObject(cipher);
System.out.println("****************** After return ****************");
printPool();
}
}
return (Key) cipher;
}
打印池
public void printPool() {
System.out.println("Pool for cipher with instances DESede/CBC/NoPadding");
System.out.println("Active [" + pool.getNumActive() + "]"); //Return the number of instances currently borrowed from this pool
System.out.println("Idle [" + pool.getNumIdle() + "]"); //The number of instances currently idle in this pool
System.out.println("Total Created [" + pool.getCreatedCount() + "]");
}
我在正确的道路上吗?是否可以增加池大小?
编辑
@http 的答案对我来说很好。但是如果我有另一种方法encryptECB(Key key, byte[] b),我该怎么写呢?
任何帮助将不胜感激!
【问题讨论】:
-
池最多有 10 个,所以如果您不将它们返回到池中,那么该错误是预期的吗?如果您想在池用完时创建更多,那么您似乎根本不需要池,您可以在需要更多时继续创建它们。
-
我走对了吗?
-
如果您想继续使用池,请不要这样做。一个池应该具有有限数量的资源,例如在这种情况下您将其设置为 10。这意味着您不能超过 10,如果它们都很忙,您需要等待一个可用,然后再请求一个。另一方面,如果您不想等待,则意味着您没有限制,因此不需要池。
-
@tima 我看到了这个example,如果池大小为空,它可以增加池大小。但不确定在我的情况下是否可以这样做。
-
你可以试试,我认为它是旧版本的 apache-commons-pool (~2012)。您也可以尝试像这样设置您的
pool.setMaxTotal(-1);,这应该允许您需要的任意数量的对象。它并没有真正增加它。
标签: java object generics apache-commons pool