【resin】 resin3 线程池与IO模型(1)
本文所讨论的线程池及IO是基于resin3.1.13开源版
resin3的线程池IO相关的类主要是3个:
Port、TcpConnection、ThreadPool
TcpConnection:处理tcp链接的task
Port:创建TcpConnection task的主线程
TreadPool:resin线程池,里面还包含了3个核心类
Item:work 线程,处理提交的task
ThreadLauncher:Daemon线程,负责创建work线程
ScheduleThread:Daemon工作线程,不断轮询task队列,有task就提交到线程池处理
下面贴出源码:为说明核心逻辑,只展示核心的代码
本文所分析为个人理解,欢迎指出不足之处或分享你的观点
在Port类中,创建的tcpconnection task,通过ThreadPool的schedule方法提交task
ThreadPool.getThreadPool().schedule(conn);
看看schedule方法:
schedule方法内部最终调用的是重载方法:
private boolean schedule(Runnable
task,
ClassLoader loader,
int freeThreads,
long expireTime,
boolean queueIfFull)
{
Item poolItem = null;
while (poolItem == null)
{
try {
synchronized ( _idleLock)
{
if (! _isInit)
init();
int idleCount = _idleCount;
int freeCount = idleCount + _threadMax - _threadCount;
boolean startNew = false;
poolItem = _idleHead;
if (poolItem != null &&
freeThreads < freeCount) {
_idleHead = poolItem. _next;
poolItem. _next = null;
poolItem. _prev = null;
poolItem. _isIdle = false;
if ( _idleHead != null)
_idleHead. _prev = null;
_idleCount--;
if (idleCount < _threadIdleMin)
startNew = true;
}
else
startNew = true;
/**
* 如果当前工作线程数不够,就通知 launcher 去创建工作线程
*/
if (startNew) {
synchronized ( _launcher)
{
_launcher.notifyAll();
}
/**
* 如果没有空闲的线程,就把task 添加到task队列里
*/
if (poolItem == null)
{
if (queueIfFull) {
synchronized ( _taskQueue)
{
_taskQueue.add(task);
_loaderQueue.add(loader);
_taskQueue.notifyAll();
}
return false;
}
。。。。。。
}
}
}
} catch (OutOfMemoryError e) {
。。。。。。
}
/**
* 有空闲的线程,就执行 提交的task
*/
poolItem.start(task, loader);
return true;
}
//从上面的代码可以看出,resin3的work线程是通过链表来维持的
//在这个方法里主要关注三点:
// 1.当前work线程不过,就notify ThreadLauncher去创建work线程
// 2.当前没有空闲的work线程,就把任务丢到task队列了 _taskQueue.add(task)
// 3.如果有work线程,就让这个线程去执行任务吧 poolItem.start(task, loader);
下面看看 ThreadLauncher 里的执行逻辑
public void run()
{
try {
for (int i
= 0; i < _threadIdleMin; i++)
startConnection(0);
} catch (Throwable e) {
e.printStackTrace();
}
while (true)
{
try {
startConnection(10000);
Thread.currentThread(). yield();
} catch (OutOfMemoryError e) {
}
}
private boolean startConnection(long waitTime)
throws InterruptedException
{
boolean doStart = true;
synchronized ( _idleLock)
{
int idleCount = _idleCount;
if (_threadMax < _threadCount + _startCount)
doStart = false;
else if (_threadIdleMin <
idleCount + _startCount)
doStart = false;
if (doStart)
_startCount++;
}
if (doStart) {
try {
Item poolItem = new Item();
Thread thread = new Thread(poolItem,
poolItem.getName());
thread.setDaemon( true);
thread.start();
} catch (Throwable e) {
}
}
else {
Thread. interrupted();
synchronized ( this)
{
wait(waitTime);
return false;
}
}
return true;
}
// ThreadLauncher 里开始会先创建 _threadIdleMin 个work线程来执行任务
// 然后会根据当前的空闲work线程数和当前active线程数的条件来创建work线程
下面看看 work线程 Item
work线程里核心的逻辑为 runTasks 方法:
private void runTasks()
{
boolean isIdle = false;
/**
* 工作线程不停轮询,直到有task可执行会 消亡
*/
while (true)
{
try {
// put the thread into the idle ring
if (! isIdle) {
isIdle = true;
synchronized ( _idleLock)
{
long now = Alarm. getCurrentTime();
if ( _threadIdleMax < _idleCount
&& _threadIdleOverflowExpire < now) {
_threadIdleOverflowExpire = now + OVERFLOW_TIMEOUT;
return;
}
_next = _idleHead;
_prev = null;
_isIdle = true;
if ( _idleHead != null)
_idleHead. _prev = this;
_idleHead = this;
_idleCount++;
}
}
Runnable task = null;
// wait for the next available task
synchronized ( this)
{
if ( _task == null)
{
wait(60000L);
}
task = _task;
_task = null;
}
// if the task is available, run it in the proper context
if (task != null)
{
isIdle = false;
try {
task.run();
} catch (Throwable e) {
} finally {
}
}
else {
boolean isDead = false;
boolean isReset = false;
// check to see if we're over the idle thread limit
synchronized ( _idleLock)
{
long now = Alarm. getCurrentTime();
if ( _isIdle
&& (( _threadIdleMax < _idleCount
&& _threadIdleOverflowExpire < now)
|| _resetCount != _threadResetCount))
{
_threadIdleOverflowExpire = now + OVERFLOW_TIMEOUT;
isDead = true;
isReset = _resetCount != _threadResetCount;
Item next = _next;
Item prev = _prev;
_next = null;
_prev = null;
_isIdle = false;
if (next != null)
next. _prev = prev;
if (prev != null)
prev. _next = next;
else
_idleHead = next;
_idleCount--;
}
}
if (isReset) {
synchronized ( _launcher)
{
_launcher.notifyAll();
}
}
/**
* 没有任务了,而且空闲线程太多了,就光荣退役好了
*/
if (isDead)
return;
}
} catch (Throwable e) {
}
}
}
}
// Item 线程主要逻辑:
// 1 把空闲的work线程放在 链表的头部
// 2 如果当前有任务,就执行任务 task.run();
// 3 如果当前没有任务,就判断空闲work数量是否过多,多了,就光荣退役了
//
最后在看看定时工作线程 ScheduleThread
public void run()
{
while (true)
{
try {
Runnable task = null;
ClassLoader loader = null;
Thread. interrupted();
synchronized ( _taskQueue)
{
if ( _taskQueue.size()
> 0) {
task = _taskQueue.remove(0);
loader = _loaderQueue.remove(0);
}
else {
try {
_taskQueue.wait(60000);
} catch (Throwable e) {
}
}
}
if (task != null)
{
schedule(task, loader, _threadIdleMin, MAX_EXPIRE, false);
}
} catch (OutOfMemoryError e) {
System. exit(10);
} catch (Throwable e) {
}
}
}
}
// 定时工作线程的目的很明确,就是不断轮询,只要task队列里有任务,就拿出来提交到线程池去执行
//