要点:
1、目前实现的线程数量不可变,且线程启动时就创建
2、“线程复用”原理是线程run方法循环等待和唤醒(等待队列插入,插入后唤醒)
3、通过线程退出run方法来达到关闭线程的目的。
4、ConcurrentLinkedDeque是单个方法级别线程安全,如果需要代码块级别的线程安全,就需要加锁。
一、代码
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.locks.LockSupport;
/**
* 启动即创建固定数量的线程,用于并发处理任务队列中的任务
* 使用ConcurrentLinkedDeque、synchronized以及LockSupport来保证线程安全
*/
public class ThreadPool {
private int poolSize;
private boolean isShutDown = false;
private List<Long> threadList = new ArrayList<>();
//任务队列
private ConcurrentLinkedDeque<Runnable> taskList = new ConcurrentLinkedDeque<>();
//当前空闲线程集合
private volatile LinkedList<Thread> waitThreads = new LinkedList<>();
/**
* 初始化线程池
*
* @param poolSize 线程数量
*/
public ThreadPool(int poolSize) {
this.poolSize = poolSize;
for (int i = 0; i < poolSize; i++) {
Thread thread = new Thread(new worker(), "t" + i);
threadList.add(thread.getId());
thread.start();
}
}
/**
* 添加Runnable类型的任务到任务队列并等待处理
*
* @param task 任务
*/
public void addTask(Runnable task) {
if (isShutDown) {
return;
}
taskList.addLast(task);//加到队尾,确保线程安全
synchronized (waitThreads) {
if (waitThreads.size() > 0) {
LockSupport.unpark(waitThreads.pollFirst());//唤醒等待中的线程