前面介紹過IoSessionRecycler是負責回收不再使用的會話的接口,ExpiringSessionRecycler是其一個實作類,用于回收逾時失效的會話。
private ExpiringMap<Object, IoSession> sessionMap;//待處理的會話集
private ExpiringMap<Object, IoSession>.Expirer mapExpirer;//負責具體的回收工作
sessionMap的鍵是由本地位址和遠端位址共同組成的,值是這兩個位址對應的會話。
Expirer類實作了Runnable接口,這個線程負責監控ExpiringMap,并把ExpiringMap中超過閥值的元素從ExpiringMap中移除。這個線程調用了setDaemon(true),是以是作為守護線程在背景運作。具體的處理過程如下:
複制代碼
private void processExpires()
{
long timeNow = System.currentTimeMillis();//目前時間
for (ExpiringObject o : delegate.values())
{
if (timeToLiveMillis <= 0)
{
continue;
}
long timeIdle = timeNow - o.getLastAccessTime();//時間差
if (timeIdle >= timeToLiveMillis)
{//逾時
delegate.remove(o.getKey());
for (ExpirationListener<V> listener : expirationListeners)
{//呼叫監聽者
listener.expired(o.getValue());
}
}
}
啟動/關閉逾時檢查線程都需要進行封鎖機制,這裡使用的是讀寫鎖:
private final ReadWriteLock stateLock = new ReentrantReadWriteLock();
public void startExpiring()
stateLock.writeLock().lock();
try
if (!running)
running = true;
expirerThread.start();
}
finally
stateLock.writeLock().unlock();
public void stopExpiring()
if (running)
running = false;
expirerThread.interrupt();
會話逾時監聽者:
private class DefaultExpirationListener implements
ExpirationListener<IoSession> {
public void expired(IoSession expiredSession) {
expiredSession.close();//關閉逾時的會話
}
本文轉自Phinecos(洞庭散人)部落格園部落格,原文連結:http://www.cnblogs.com/phinecos/archive/2008/12/04/1347752.html,如需轉載請自行聯系原作者