前面介紹過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()
{
stateLock.writeLock().lock();
try
{
if (running)
{
running = false;
expirerThread.interrupt();
}
}
finally
{
stateLock.writeLock().unlock();
}
}
會話逾時監聽者:
private class DefaultExpirationListener implements
ExpirationListener<IoSession> {
public void expired(IoSession expiredSession) {
expiredSession.close();//關閉逾時的會話
}
}
作者:phinecos(洞庭散人)
出處:http://phinecos.cnblogs.com/
本文著作權歸作者和部落格園共有,歡迎轉載,但請保留此段聲明,並在文章頁面明顯位置給出原文串連。
作者:洞庭散人
出處:http://phinecos.cnblogs.com/
本部落格遵從Creative Commons Attribution 3.0 License,若用於非商業目的,您可以自由轉載,但請保留原作者資訊和文章連結URL。