代码demo再谈Java线程池
上代码
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadPool {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1), new DefaultThreadFactory());
for (int i = 0; i < 5; i++) {
final int data = i;
try {
executor.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + ":" + data);
}
});
} catch (Exception e) {
System.out.println(data + ":error");
}
}
executor.shutdown();
}
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "MYPOOL-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
}
结果如下
4:error
Thread[MYPOOL-1-thread-3,5,main]:3
Thread[MYPOOL-1-thread-2,5,main]:1
Thread[MYPOOL-1-thread-1,5,main]:0
Disconnected from the target VM, address: '127.0.0.1:54382', transport: 'socket'
Thread[MYPOOL-1-thread-3,5,main]:2
结果发现运行成功的只有4个线程,(为什么会是4个而不是3个 因为队列的容量为1 ,最大线程数为3 ) 拒绝策略我用的直接抛出异常第5个任务捕捉到异常error,
大致流程步骤
1.当工作线程数 < corePoolSize 时,新创建一个新线程执行新提交任务,即使此时线程池中存在空闲线程;
2.当工作线程数 == corePoolSize 时,新提交任务将被放入 workQueue 中;
3.当 workQueue 已满,且工作线程数 < maximumPoolSize 时,新提交任务会创建新的非核心线程执行任务;
4.当 workQueue 已满,且 工作线程数==maximumPoolSize 时,新提交任务由 RejectedExecutionHandler 处理
流程图
java并发编程艺术
public void execute(Runnable command) {
// 提交任务不能为 null
if (command == null)
throw new NullPointerException();
// 获取控制位 ctl 的值
int c = ctl.get();
// work 线程数 < 核心线程数
if (workerCountOf(c) < corePoolSize) {
// 直接创建核心线程,执行任务
if (addWorker(command, true))
return;
/*
因为没有使用锁,可能会出现并发创建核心线程;
走到这里,说明核心线程已经创建满了,此时,重新获取控制位 ctl 的值
*/
c = ctl.get();
}
// 如果线程池还是 RUNNING 状态,并且任务成功提交到阻塞队列中
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
// double-check,再检查一次线程池状态
// 如果线程池变成非 RUNNING 状态,则回滚刚才新加的任务
if (! isRunning(recheck) && remove(command))
// 从阻塞队列中移除任务成功,使用拒绝策略执行任务
reject(command);
// 如果工作线程数==0,则添加一个线程
// 主要是兼容核心线程数==0 的情况
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
/*
到达这里,则说明核心线程数已满,且阻塞队列已满
尝试创建非核心线程执行任务
*/
else if (!addWorker(command, false))
// 非核心线程创建失败了,说明是线程数以达到 maximumPoolSize,此时执行拒绝策略
reject(command);
}
private boolean addWorker(Runnable firstTask, boolean core) {
// 定义了一个 retry 标签
retry:
for (;;) {
// 获取控制位
int c = ctl.get();
// 获取运行状态
int rs = runStateOf(c);
/**
* rs >= SHUTDOWN:即非 RUNNING 状态,只有 RUNNING < SHUTDOWN
* ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())
* 等价于 非 SHUTDOWN 态 || firstTask != null || workQueue.isEmpty()
* 非 SHUTDOWN 态 == true:SHUTDOWN 态之后的状态,都不允许再添加 worker 线程了,直接返回 false;
* 非 SHUTDOWN 态 == false || (firstTask != null) == true:SHUTDOWN 状态下,不允许再添加任务了,返回 false;
* 非 SHUTDOWN 态 == false || (firstTask != null) == false || workQueue.isEmpty() == true:SHUTDOWN 状态,没提交新任务,阻塞队列又是空的,没必要再添加线程了
*/
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
// CAS 创建 worker 线程
for (;;) {
// 获取线程数
int wc = workerCountOf(c);
/*
当前线程数大于最大值
或
当前创建的是核心线程,但线程数量已经>=核心线程数
或
当前创建非核心线程,但线程数量已经>=maximumPoolSize
*/
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
// 不创建,直接返回 false
return false;
// cas 修改 ctl 中的线程数,线程数+1
if (compareAndIncrementWorkerCount(c))
// cas 修改成功,break goto 结束循环(不会再进入标签下的循环)
break retry;
// 达到这里,说明 cas 增加线程数 1 失败了,此时进行尝试
c = ctl.get();
// 先判断一下线程池状态有没有改变,如果改变了,则 continue goto(会再进入标签下的循环)
// 跳转到最外层的循环,重新检测线程池的状态值
if (runStateOf(c) != rs)
continue retry;
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
// 创建 worker 对象
w = new Worker(firstTask);
// 获取 worker 的线程
final Thread t = w.thread;
if (t != null) {
// 加锁
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 获取线程池状态
int rs = runStateOf(ctl.get());
/*
线程池是 RUNNING 状态
或
SHUTDOWN 态 且 firstTask == null(这种情况是需要创建线程,消费队列中剩余的任务)
*/
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
// 线程是活动状态,则不合法,因为线程是刚创建的,应该是 NEW 状态
if (t.isAlive())
throw new IllegalThreadStateException();
// 将 worker 添加到 list 中
workers.add(w);
// largestPoolSize 记录该线程池使用过程中,达到最大的线程数
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
// worker 添加成功,workerAdded 置为 true
workerAdded = true;
}
} finally {
mainLock.unlock();
}
// worker 添加成功,此时就可以启动线程
if (workerAdded) {
t.start();
// 启动线程成功,workerStarted 置为 true
workerStarted = true;
}
}
} finally {
// 如果 worker 启动失败,则移除它
if (! workerStarted)
// workers 移除新加的 worker,并在 ctl 中将 work 线程数量-1
addWorkerFailed(w);
}
return workerStarted;
}