type
status
date
slug
summary
tags
category
icon
password
几种预定义的线程池
newFixedThreadPool
newSingleThreadExecutor
newCachedThreadPool
这里使用的
SynchronousQueue
并不存储任务,因此这个线程池如果来了任务直接交给线程去执行,如果没有空闲的线程就创建,否则复用.submit vs execute
有两种提交任务的方式:
- execute(Runnable r)
不返回结果
- submit(Runnbale r)
有一个Future的返回结果.
可以看到,使用submit()提交Runnable,会使用一个
RUnnableFuture
包装Runnable,以返回任务结果.ThreadPoolExecutor中线程池的几种状态
翻译成二进制即:
线程池的控制状态存放在一个AtomicInteger中,一共32位:
- 高3位表示5种运行状态,即runState
为什么用3位表示?其实这里就是个简单的状态机而已,2位最多表示4种状态,3位最多表示8种状态,因此这里选择3位来表示.
- 低29位表示有效线程数,即workerCount
线程池的5种状态
- Running
可以接受新任务和处理队列中的任务
- Shutdown
不接受新任务,但是可以处理队列中的任务
- Stop
不接受新任务,也不处理队列中的任务,并且中断正在处理的任务
- Tidying
所有的任务已经终止了.workerCount = 0,过渡到这个状态的线程将会调用
terminated()
方法- Terminated
terminated()
已经执行完毕
再来看一下这些位操作:
Worker
Worker本身也是Runnable,run的时候实际上运行的也是任务,而且Worker持有了Thread和Runnable,并且为线程增加了中断控制的能力.
从代码上可以看出,Worker是复用的,不同的任务(Runnable)可能会添加到同一个Worker中,换句话说一个Worker对应一个线程,一个线程可能会运行多个任务.
execute(Runnable r)执行过程
基本上都是一些状态判断,然后试图添加worker.
状态何时会启动线程,执行任务.
总结
看看注释说明得了,把机制弄清楚.
代码写的真的是一言难尽.if else太多,各种稀奇古怪的判断看起来真的没什么意思.
- 作者:姜康
- 链接:https://jiangkang.tech/article/f6dde6fa-5174-4dda-bde3-aabfb6fd9e11
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。