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,排队有三种通用策略: