我正在研究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;
}
//
}这就是我如何在示例类中实现ObjectPool的方法。
public Key aKey(byte[] tmkByte) 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(tmkByte);
SecretKey tmk = new SecretKeySpec(de, "DESede");
return tmk;
} 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() + "]");
}有趣的部分来了。当我运行我的应用程序时,我得到了以下输出:
****************** After borrow ****************
Pool for cipher with instances DESede/CBC/NoPadding
Active [1]
Idle [0]
Waiter [0]
Total Created [1]
****************** After return ****************
Pool for cipher with instances DESede/CBC/NoPadding
Active [0]
Idle [1]
Waiter [0]
Total Created [1]如果我在没有returnObject到pool的情况下运行应用程序3次
****************** After borrow ****************
Pool for cipher with instances DESede/CBC/NoPadding
Active [1]
Idle [0]
Waiter [0]
Total Created [1]
****************** After return ****************
Pool for cipher with instances DESede/CBC/NoPadding
Active [1]
Idle [0]
Waiter [0]
Total Created [1]
****************** After borrow ****************
Pool for cipher with instances DESede/CBC/NoPadding
Active [2]
Idle [0]
Waiter [0]
Total Created [2]
****************** After return ****************
Pool for cipher with instances DESede/CBC/NoPadding
Active [2]
Idle [0]
Waiter [0]
Total Created [2]
****************** After borrow ****************
Pool for cipher with instances DESede/CBC/NoPadding
Active [3]
Idle [0]
Waiter [0]
Total Created [3]
****************** After return ****************
Pool for cipher with instances DESede/CBC/NoPadding
Active [3]
Idle [0]
Waiter [0]
Total Created [3]如果我跑了10多次,我就会如愿以偿:
java.util.NoSuchElementException:等待空闲对象的超时
基于输出和代码,我是否正确地实现?
发布于 2017-05-09 23:49:42
看起来不错,除了: activateObject/passivateObject方法:我没有看到运行变量的任何用法?除此之外,您也不需要在这个方法中做任何事情,它将被调用,在返回对象之前,我不认为这是密码实例所需要的,不是吗?
但是我要回答的原因是:我很肯定你不会因为密码实例使用池而获得任何好处。池的管理、同步、代码维护和附加库将使用更多的资源。
一般的规则是,“按定义”:代码越多意味着性能越低。当然,这并不是完全正确的--我想说的是:如果你想提高性能,你必须在你的改变之前和之后进行测量。不仅仅是millis,还有cpu、内存、gc、io等等。你必须确定的是,你的改变确实取得了进步,而不是相反。
希望能帮上忙..。
https://codereview.stackexchange.com/questions/162914
复制相似问题