jetty的线程池-QueuedThreadPool

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

jetty的线程池-QueuedThreadPool
一直对线程池有些疑问:
1.线程池怎么保证线程一直存在?
2.线程池怎么控制最大空闲时间?
3.线程池怎么回收线程?。

带着这些问题,看了一边jetty的线程池。

jetty有三个线程池,分别是ExecutorThreadPool,OldQueuedThreadPool,QueuedThreadPool
它们都实现了org.eclipse.jetty.util.thread.ThreadPool接口,并继承ponent.AbstractLifeCycle
这里我们只关注QueuedThreadPool。

看名字就知道,它是跟队列相关的,没错。

QueuedThreadPool的存放jbos的集合(BlockingQueue<Runnable> ),
和存放线程的集合都是用队列实现的(ConcurrentLinkedQueue<Thread>)
看看QueuedThreadPool前面定义的private属性:
Java代码
1.public class QueuedThreadPool extends AbstractLifeCycle impleme
nts ThreadPool, Executor {
2. //已经启动的线程数
3. private final AtomicInteger _threadsStarted
= new AtomicInteger();
4. //空闲线程数
5. private final AtomicInteger _threadsIdle
= new AtomicInteger();
6.//上一次执行销毁线程的时间。

这个就是用来控制最大空闲时间的
7. private final AtomicLong _lastShrink
= new AtomicLong();
8.//存放线程的集合
9. private final ConcurrentLinkedQueue<Thread> _threads
= new ConcurrentLinkedQueue<Thread>();
10.//一个锁
11. private final Object _joinLock
= new Object();
12.//存放任务的集合
13. private BlockingQueue<Runnable> _jobs;
14.//以上这些都是线程安全的
15.
16.//下面这些都是参数,不会变的,所以无需线程安全控制
17. private String _name;
18. private int _maxIdleTimeMs
= 60000;
19. private int _maxThreads
= 254;
20. private int _minThreads
= 8;
21. private int _maxQueued
= -1;
22. private int _priority
= Thread.NORM_PRIORITY;
23. private boolean _daemon
= false;
24. private int _maxStopTime
= 100;
jetty里面的核心类都实现了lifecycle接口,所以该线程池初始化的时候,是调用的doStart()方法。

Java代码
1.protected void doStart() throws Exception {
2. super.doStart();
3. _threadsStarted.set(0);
4.
5. if (_jobs == null) {
6. _jobs = _maxQueued > 0 ? new ArrayBlockingQueue<Runna
ble>(_maxQueued) : new BlockingArrayQueue<Runnable>( 7.
_minThreads ,
8.
_minThreads );
9. }
10.
11. int threads = _threadsStarted.get();
12. // 启动一定数量的线程
13. while (isRunning() && threads < _minThreads) {
14. //启动线程
15. startThread(threads);
16. threads = _threadsStarted.get();
17. }
18. }
首先初始化了父类,接着设置已经启动的线程数=0,设置存放jbos的集合。

然后就开始启动线程了。

直到已经启动的线程数=最小线程数。

至此,完成初始化。

再来看看startThread方法:
Java代码
1................
2. Thread thread = newThread(_runnable);
3. thread.setDaemon(_daemon);
4. thread.setPriority(_priority);
5. thread.setName(_name + "-" + thread.getId());
6. _threads.add(thread);
7. thread.start();
8. ..............
仅仅是启动了一个_runnable对象。

其他的都没啥好看的。

赶紧看看这个_runnable是咋样的。

_runnable是一个runnable的匿名类,它的run方法里是一个while循环Java代码
1.while (isRunning()) {
2. 1.loop jobs
3. 2.阻塞或者回收线程
1.循环的从任务队列里面取任务,直到任务队列为空
Java代码
1.// 首先把jobs里面的任务都执行掉
2./ 首先把jobs里面的任务都执行掉
3. while (job != null && isRunning()) {
4. job.run();
5. // jbos.poll()不阻塞,如果木有,直接返回null
6. job = _jobs.poll();
7. }
2.接着,阻塞线程,回收线程
Java代码
1.// 没有可执行的任务,空闲线程数量+1
2. _threadsIdle.incrementAndGet();
3. // 木有任务的情况下,使劲循环
4. while (isRunning() && job == null) {
5. // jbos.take()会阻塞,直到有一个job返回,这样就维持
了线程一直存在着
6. // 最大空闲时间<=0,则不回收线程,直接阻塞线程,等待任务
7. if (_maxIdleTimeMs <= 0) job = _jobs.take();
8. else {
9. // maybe we should shrink?
10. // 已经启动的线程数
11. final int size = _threadsStarted.get();
12. // 已经启动的线程数>_minThreads,判断是否需要回收
13. if (size > _minThreads) {
14. // 上一次回收线程的时间
15. long last = _lastShrink.get();
16. // now
17. long now = System.currentTimeMillis();
18. // 两次回收之间的时间间隔>最大空闲时间
19. if (last == 0 || (now - last) > _maxIdleTimeMs) {
20. // 回收掉
21. shrink = _pareAndSet(last, now)
22. && _pareAndSet(size,
23. size -
1);
24. if (shrink) return;
25. }
26. }
27. // 阻塞最大空闲时间,然后返回。

28. // 这次返回以后,如果让然没有任务可执行,并且启动的线程
数>_minThreads,则会回收掉
29. job = _jobs.poll(_maxIdleTimeMs, LIS
ECONDS);
30. }
31. }。

相关文档
最新文档