mina源碼分析二(轉)

這一篇主要介紹實現這些接口的抽象基類。首先是實現IoService接口的AbstractIoService類。它包含了一個Executor來處理到來的事件。每個AbstractIoService都一個AtomicInteger類型的id號,確保每個id的唯一性。

它內部的Executor可以選擇是從外部傳遞進構造函數中,也可以在實例內部自行構造,若是後者,則它將是ThreadPoolExecutor類的一個實例,即是Executor線程池中的一員。代碼如下:

if (executor == null) 

        {

            this.executor = Executors.newCachedThreadPool();

            createdExecutor = true;

        } 

        else 

        {

            this.executor = executor;

            createdExecutor = false;

        }

它內部的Executor可以選擇是從外部傳遞進構造函數中,也可以在實例內部自行構造,若是後者,則它將是ThreadPoolExecutor類的一個實例,即是Executor線程池中的一員。代碼如下:

其中有一個IdleStatusChecker成員,它用來對服務的空閒狀態進行檢查,在一個服務激活時會將服務納入到檢查名單中,而在服務失效時會將服務從名單中剔除。會單獨開一個線程進行具體的空閒檢查,這是通過下面這個線程類來負責的:

private class NotifyingTaskImpl implements NotifyingTask 

{

        private volatile boolean cancelled;//取消檢查標誌

        private volatile Thread thread;

        public void run()

{

            thread = Thread.currentThread();

            try {

                while (!cancelled) 

{

                    //每隔1秒檢查一次空閒狀態

                    long currentTime = System.currentTimeMillis();

                    notifyServices(currentTime);

                    notifySessions(currentTime);

                    try 

{

                        Thread.sleep(1000);

                    } catch (InterruptedException e) 

{

                        // will exit the loop if interrupted from interrupt()

                    }

                }

            }

 Finally

 {

                thread = null;

            }

        }

}

具體的空閒檢查代碼如下,超過能容忍的最大空閒時間,就會fire出SessionIdle事件,上文也說過空閒有三種類型:讀端空,寫端空,雙端空。

notifyIdleSession1(s, currentTime,

                s.getConfig().getIdleTimeInMillis(IdleStatus.BOTH_IDLE),IdleStatus.BOTH_IDLE,Math.max(s.getLastIoTime(),s.getLastIdleTime(IdleStatus.BOTH_IDLE)));

    private static void notifyIdleSession1(

            AbstractIoSession session, long currentTime,

            long idleTime, IdleStatus status, long lastIoTime) 

{

        if (idleTime > 0 && lastIoTime != 0

                && currentTime - lastIoTime >= idleTime) 

{

            session.getFilterChain().fireSessionIdle(status);

        }

}

在釋放資源的方法時,首先去獲取釋放鎖disposalLock才行,然後具體的釋放動作是通過dispose0完成的,接着取消掉空閒檢查線程,此外,若線程是內部創建的線程池中的一員,則通過線程池去關閉線程。

public final void dispose() 

{

        IoFuture disposalFuture;

        synchronized (disposalLock) 

{//獲取釋放鎖

            disposalFuture = this.disposalFuture;

            if (!disposing) {

                disposing = true;

                try {

                    this.disposalFuture = disposalFuture = dispose0();//具體釋放動作

                } catch (Exception e) {

                    ExceptionMonitor.getInstance().exceptionCaught(e);

                } finally {

                    if (disposalFuture == null) {

                        disposed = true;

                    }

                }

            }

        }

        idleStatusChecker.getNotifyingTask().cancel();

        if (disposalFuture != null)

{//無中斷地等待釋放動作完成

            disposalFuture.awaitUninterruptibly();

        }

        if (createdExecutor) 

{通過線程池去關閉線程

            ExecutorService e = (ExecutorService) executor;

            e.shutdown();

            while (!e.isTerminated()) {

                try {

                    e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);

                } catch (InterruptedException e1) {

                    // Ignore; it should end shortly.

                }

            }

        }

        disposed = true;

    }

 再來看會話初始化完成後的動作每個session都保持有自己的屬性映射圖,在會話結束初始化時,應該設置這個AttributeMap

((AbstractIoSession) session).setAttributeMap(session.getService()
                     .getSessionDataStructureFactory().getAttributeMap(session));

除此以爲,還應該爲會話配置寫請求隊列:

((AbstractIoSession) session).setWriteRequestQueue(session
                     .getService().getSessionDataStructureFactory()
                     .getWriteRequestQueue(session));

在初始化時會在會話的屬性中加入一項SESSION_CREATED_FUTURE,這個屬性會在連接真正建立後從會話中去除。

  if (future != null && future instanceof ConnectFuture) 
 {
            session.setAttribute(DefaultIoFilterChain.SESSION_CREATED_FUTURE,
                     future);
  }

用戶特定的初始化動作在finishSessionInitialization0這個方法中自行實現。




發佈了182 篇原創文章 · 獲贊 7 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章