admin管理员组文章数量:1567738
2023年12月13日发(作者:)
jetty的线程池-QueuedThreadPool
一直对线程池有些疑问:
1.线程池怎么保证线程一直存在?
2.线程池怎么控制最大空闲时间?
3.线程池怎么回收线程?
。。。。
带着这些问题,看了一边jetty的线程池。
jetty有三个线程池,分别是ExecutorThreadPool,OldQueuedThreadPool,QueuedThreadPool
它们都实现了Pool接口,并继承ctLifeCycle
这里我们只关注QueuedThreadPool。
看名字就知道,它是跟队列相关的,没错。
QueuedThreadPool的存放jbos的集合(BlockingQueue
和存放线程的集合都是用队列实现的(ConcurrentLinkedQueue
看看QueuedThreadPool前面定义的private属性:
Java代码
1. public class QueuedThreadPool extends AbstractLifeCycle implements 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
= new ConcurrentLinkedQueue
10.//一个锁
11. private final Object _joinLock
= new Object();
12.//存放任务的集合
13. private BlockingQueue
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
= _PRIORITY;
23. private boolean _daemon
= false;
24. private int _maxStopTime
= 100;
jetty里面的核心类都实现了lifecycle接口,所以该线程池初始化的时候,是调用的doStart()方法。
Java代码
1. protected void doStart() throws Exception {
2. t();
3. _(0);
4.
5. if (_jobs == null) {
6. _jobs = _maxQueued > 0 ? new ArrayBlockingQueue
7.
_minThreads,
8.
_minThreads);
9. }
10.
11. int threads = _();
12. // 启动一定数量的线程
13. while (isRunning() && threads < _minThreads) {
14. //启动线程
15. startThread(threads);
16. threads = _();
17. }
18. } 首先初始化了父类,接着设置 已经启动的线程数=0,设置存放jbos的集合。
然后就开始启动线程了。直到已经启动的线程数=最小线程数。
至此,完成初始化。
再来看看startThread方法:
Java代码
1. ...............
2. Thread thread = newThread(_runnable);
3. mon(_daemon);
4. ority(_priority);
5. e(_name + "-" + ());
6. _(thread);
7. ();
8. ..............
仅仅是启动了一个_runnable对象。其他的都没啥好看的。
赶紧看看这个_runnable是咋样的。
_runnable是一个runnable的匿名类,它的run方法里是一个while循环
Java代码
1. while (isRunning()) {
2. jobs
3. 2.阻塞或者回收线程
1.循环的从任务队列里面取任务,直到任务队列为空
Java代码
1. // 首先把jobs里面的任务都执行掉
2. / 首先把jobs里面的任务都执行掉
3. while (job != null && isRunning()) {
4. ();
5. // ()不阻塞,如果木有,直接返回null
6. job = _();
7. }
2.接着,阻塞线程,回收线程 Java代码
1. // 没有可执行的任务,空闲线程数量+1
2. _entAndGet();
3. // 木有任务的情况下,使劲循环
4. while (isRunning() && job == null) {
5. // ()会阻塞,直到有一个job返回,这样就维持了线程一直存在着
6. // 最大空闲时间<=0,则不回收线程,直接阻塞线程,等待任务
7. if (_maxIdleTimeMs <= 0) job = _();
8. else {
9. // maybe we should shrink?
10. // 已经启动的线程数
11. final int size = _();
12. // 已经启动的线程数>_minThreads,判断是否需要回收
13. if (size > _minThreads) {
14. // 上一次回收线程的时间
15. long last = _();
16. // now
17. long now = tTimeMillis();
18. // 两次回收之间的时间间隔>最大空闲时间
19. if (last == 0 || (now - last) > _maxIdleTimeMs) {
20. // 回收掉
21. shrink = _eAndSet(last, now)
22. && _eAndSet(size,
23. size - 1);
24. if (shrink) return;
25. }
26. }
27. // 阻塞最大空闲时间,然后返回。
28. // 这次返回以后,如果让然没有任务可执行,并且启动的线程数>_minThreads,则会回收掉
29. job = _(_maxIdleTimeMs, ECONDS);
30. }
31. }
版权声明:本文标题:jetty的线程池-QueuedThreadPool 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1702479474a9177.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论