1、线程池
在Jetty 8 中实现了两个线程池,ExcutorThreadPool和QueuedThreadPool。其中ExcutorThreadPool是对java已有线程池的封装,而QueuedThreadPool是对Executor的实现。下面来看一下这两个线程池的定义。
/* ------------------------------------------------------------ */
/**
* Jetty ThreadPool using java 5 ThreadPoolExecutor
* This class wraps a {@link ExecutorService} as a {@link ThreadPool} and
* {@link LifeCycle} interfaces so that it may be used by the Jetty <code>org.eclipse.jetty.server.Server</code>
*/
public class ExecutorThreadPool extends AbstractLifeCycle implements ThreadPool, LifeCycle
public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPool, Executor, Dumpable
2、QueuedThreadPool的实现
2.1 、属性
// 已经启动的线程数目
private final AtomicInteger _threadsStarted = new AtomicInteger();
// 空闲的线程数目
private final AtomicInteger _threadsIdle = new AtomicInteger();
//
private final AtomicLong _lastShrink = new AtomicLong();
// 所有启动的线程的集合
private final ConcurrentLinkedQueue<Thread> _threads=new ConcurrentLinkedQueue<Thread>();
// 共享变量
private final Object _joinLock = new Object();
// 阻塞队列,用于存放需要执行的job
private BlockingQueue<Runnable> _jobs;
// _name
private String _name;
// 最大空闲时间,这里应该可以理解为线程池中有空闲的线程的最大的持续时间
private int _maxIdleTimeMs=60000;
// 最大线程数
private int _maxThreads=254;
// 最下线程数
private int _minThreads=8;
// 最大排队
private int _maxQueued=-1;
// 线程优先级
private int _priority=Thread.NORM_PRIORITY;
// 是否是守护线程
private boolean _daemon=false;
// 最大stop时间
private int _maxStopTime=100;
private boolean _detailedDump=false;
2.2、构造函数
/* ------------------------------------------------------------------- */
/** Construct
*/
public QueuedThreadPool()
{
// 设置线程名称以qtp开头
_name="qtp"+super.hashCode();
}
/* ------------------------------------------------------------------- */
/** Construct
*/
public QueuedThreadPool(int maxThreads)
{
this();
// 设置最大线程数
setMaxThreads(maxThreads);
}
/* ------------------------------------------------------------------- */
/** Construct
*/
public QueuedThreadPool(BlockingQueue<Runnable> jobQ)
{
this();
// 设置阻塞队列
_jobs=jobQ;
// 清除阻塞队列
_jobs.clear();
}
2.3、启动线程池
实际启动线程是通过doStart()函数。
@Override
protected void doStart() throws Exception
{
// 调用父类doStart()
super.doStart();
// 设置_threadsStarted为0,则表示线程从0开始编号
_threadsStarted.set(0);
// 如果_jobs为空,则为线程池添加默认队列。
if (_jobs==null)
{
// 如果_maxQueued大于0,则创建ArrayBlockingQueue,大小为_maxQueued
// 如果_maxQueued小于等于0,则创建BlockingArrayQueue,大小为_minThreads,可增长为_minThreads
_jobs=_maxQueued>0 ?new ArrayBlockingQueue<Runnable>(_maxQueued)
:new BlockingArrayQueue<Runnable>(_minThreads,_minThreads);
}
// 获取线程编号初始值
int threads=_threadsStarted.get();
// 启动线程数为_minThreads,默认为8
while (isRunning() && threads<_minThreads)
{
// 启动线程,编号为threads
startThread(threads);
threads=_threadsStarted.get();
}
}