【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队列里有任务,就拿出来提交到线程池去执行
//