http://www.iteye.com/topic/1112123java
http://dongxuan.iteye.com/blog/901689服務器
http://scholers.iteye.com/blog/1452780多線程
基本流程性能
一、服務端監聽端口是否有鏈接創建,接收到請求,建立IoSessionspa
二、IoProcessor輪訓IO通道,處理IO操做(讀寫),從線程池調用IoHandler線程處理工做操作系統
三、IoHandler處理工做線程
幾個主要的概念:
一、線程
Mina2中在三個地方使用了線程:netty
IoAcceptor接收客戶端的鏈接創建,每監聽一個端口(調一次bind()方法)啓用一個線程;每接收到一次請求,建立一個IoSession對象,由於建立IoSession對象的速度足夠快,因此一個線程就夠了。code
IoConnector用於與服務端創建鏈接,每鏈接一個服務器(調用一次connect()方法),建立一個IoSession對象。對象
真正執行IO操做的線程,默認啓用的線程數是CPU和核數+1,如單CPU雙核電腦,默認的IoProcessor就會建立3個,也就是說一個IoAcceptor/IoConnector會關聯一個 IoProcessor池,這個池中有3個IoProcessor。
爲何IoProcessor比CPU核數大一?由於IO操做耗費資源。可是通常實現的時候都採用工做線程與IO線程分離,而且如今的CPU性能已經大大的提高了,因此能夠根據實際配置適當增長。如:netty中默認爲cpu個數*2+1。
IoProcessor的構造方法有一個參數是java.util.concurrent.Executor,這個參數就是讓IO線程與工做線程分離的關鍵,也就是讓IoProcessor調用的IoHandler中的某些方法(MessageReceived()等)在線程池中分配的線程獨立運行,而不是在IoProcessor所在的線程。即:acceptor.getFilterChain().addLast(「threadpool」, new ExcetorFilter());這行代碼設置的若是不指定ExcetorFilter參數,默認使用OrderedThreadPoolExecutor
二、線程隊列
OrderedThreadPoolExecutor等*Executor都是是繼承自ThreadPoolExecutor,區別在於隊列大小、隊列類型上。IoAcceptor實現NioSocketAcceptor默認用的是ExecutorService.newCachedThreadPool(),這是一個無界的線程池,而且隊列是一個同步隊列。
代碼以下:
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
ThreadPoolExecutor共有6個構造參數:
corePoolSize:線程池維護線程的最少數量
maximumPoolSize:線程池維護線程的最大數量
keepAliveTime:線程池維護線程所容許的空閒時間
unit:線程池維護線程所容許的空閒時間的單位
workQueue:線程池所使用的緩衝隊列
handler:線程池對拒絕任務的處理策略
排隊規則:
A. 若是運行的線程少於corePoolSize,則Executor始終首選添加新的線程,而不進行排隊。
B. 若是運行的線程等於或多於corePoolSize,則Executor始終首選將請求加入隊列,而不添加新的線程。
C. 若是沒法將請求加入隊列,則建立新的線程,除非建立此線程超出maximumPoolSize,在這種狀況下,任務將被拒絕。
對於workQueue,排隊有三種通用策略: