简易版线程池
一切尽在代码中。。。
线程池类
/**
* @Author Mr.wei
* @Date 2020/2/18 15:00
* @Description:没有核心线程与非核心线程概念、删减了状态(RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED)、没添加结束方法......
*/
public class CThreadPoolExecutor {
/**
* 线程池大小
*/
private int poolSize;
/**
* 线程存活时间
*/
private int keepAlive;
/**
* 时间单位
*/
private TimeUnit unit;
/**
* 存放任务的阻塞队列
*/
private BlockingQueue<Runnable> queue;
/**
* 拒绝策略
*/
private CRejectPolicy rejectPolicy;
/**
* 线程工厂
*/
private ThreadFactory threadFactory;
/**
* 完成任务数
*/
private volatile long completeTaskCount;
/**
* 主锁
*/
private ReentrantLock mainLock = new ReentrantLock(true);
/**
* 工作者集合
*/
private HashSet<Worker> workerSet = new HashSet<>();
/**
* 工作线程计数器
*/
private AtomicInteger ctl = new AtomicInteger(0);
public CThreadPoolExecutor(int poolSize, int keepAlive, TimeUnit unit, BlockingQueue queue, CRejectPolicy rejectPolicy) {
this.poolSize = poolSize;
this.keepAlive = keepAlive;
this.unit = unit;
this.queue = queue;
this.rejectPolicy = rejectPolicy;
this.threadFactory = new DefaultThreadFactory();
}
public CThreadPoolExecutor(int poolSize, int keepAlive, TimeUnit unit, BlockingQueue queue, CRejectPolicy rejectPolicy, ThreadFactory threadFactory) {
this.poolSize = poolSize;
this.keepAlive = keepAlive;
this.unit = unit;
this.queue = queue;
this.rejectPolicy = rejectPolicy;
this.threadFactory = threadFactory;
}
private class Worker implements Runnable {
/**
* 线程
*/
private Thread thread;
/**
* 第一个唤醒该线程的任务
*/
private Runnable firstTask;
/**
* 该工作者完成的任务数
*/
private int completeTaskCount = 0;
Worker(Runnable firstTask) {
this.thread = threadFactory.creatThread(this);
this.firstTask = firstTask;
}
@Override
public void run() {
runWorker(this);
}
}
/**
* 通过worker中的线程执行的任务,其种类有两种:
* 1. worker中的第一个任务
* 2. 从queue中取得任务
* 没有任务的话超过一定的时间就自动消除。
*
* @param worker
*/
private void runWorker(Worker worker) {
Runnable task = worker.firstTask;
worker.firstTask = null;
//判断任务时正常结束,还是因为异常结束
boolean completedAbruptly = true;
try {
//获取任务并执行,这个while是线程复用的精髓,其中getTask是精髓中的精髓
while (task != null || (task = getTask()) != null) {
try {
task.run();
} finally {
task = null;
completeTaskCount++;
}
}
completedAbruptly = false;
} finally {
processWorkerExit(worker, completedAbruptly);
}
}
/**
* 任务的结束
*
* @param w
* @param completedAbruptly
*/
private void processWorkerExit(Worker w, boolean completedAbruptly) {
int i = ctl.get();
if (completedAbruptly) {
decrementCtl(i);
}
ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completeTaskCount += w.completeTaskCount;
workerSet.remove(w);
} finally {
mainLock.unlock();
}
//如果不是正常结束,且队列里不为空,且线程池中线程数还未上限则增加一个线程
if (completedAbruptly && !queue.isEmpty() && i < poolSize) {
addWorker(null);
}
}
/**
* 从队列中获取任务
*
* @return
*/
private Runnable getTask() {
boolean timeOut = false;
for (; ; ) {
//如果队列是空的,并且已经超过了空闲时间,那就减小线程数
if (queue.isEmpty() && timeOut) {
decrementCtl(ctl.get());
return null;
}
try {
Runnable r = queue.poll(keepAlive, unit);
if (null != r) {
return r;
}
timeOut = true;
} catch (InterruptedException e) {
}
}
}
/**
* 减少工作线程数
*
* @param expect
*/
private void decrementCtl(int expect) {
do {
} while (!ctl.compareAndSet(expect, expect - 1));
}
/**
* 增加工作线程数
*
* @param expect
*/
private boolean incrementCtl(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
/**
* 该方法有三种情况:
* 1. 当线程池中线程数没超过指定线程数,则使用直接addworker
* 2. 当线程池中的线程满了,但队列没满时,则添加到队列
* 3. 当线程池和队列都满了,按照给定的策略去执行
*
* @param r
*/
public void execute(Runnable r) {
if (null == r) {
throw new NullPointerException();
}
if (ctl.get() < poolSize) {
addWorker(r);
} else if (queue.offer(r)) {
if (ctl.get() == 0) {
addWorker(null);
}
} else {
rejectPolicy.reject(r);
}
}
/**
* 添加Worker
*
* @param r
* @return
*/
private boolean addWorker(Runnable r) {
Worker worker = new Worker(r);
ReentrantLock mainLock = this.mainLock;
mainLock.lock();
boolean workerAdded = false;
boolean workerStarted = false;
for (; ; ) {
int c = ctl.get();
//判断线程数量是否已经达到线程池指定大小
if (c == poolSize) {
return false;
}
//这里说明线程数量没有达到线程池指定大小,尝试去增加线程大小
if (incrementCtl(c)) {
break;
}
}
try {
try {
// 向worker集中添加除worker
workerSet.add(worker);
workerAdded = true;
} finally {
mainLock.unlock();
}
// 添加成功就启动线程
if (workerAdded) {
Thread thread = worker.thread;
thread.start();
workerStarted = true;
}
} finally {
// 启动线程失败之后的处理
if (!workerStarted) {
addWorkerFailed(worker);
}
}
return workerStarted;
}
/**
* 添加失败,处理两步走:
* 1. 从worker集中移除worker
* 2. 减少线程数
*
* @param worker
*/
private void addWorkerFailed(Worker worker) {
ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
workerSet.remove(worker);
decrementCtl(ctl.get());
} finally {
mainLock.unlock();
}
}
}
线程工厂
接口
/**
* @Author Mr.wei
* @Date 2020/2/18 15:25
* @Description:线程工厂接口
*/
public interface ThreadFactory {
/**
* 创建线程
*
* @return 创建好的线程
*/
public Thread creatThread(Runnable runnable);
}
实现类
/**
* @Author Mr.wei
* @Date 2020/2/18 15:31
* @Description:默认线程工厂
*/
public class DefaultThreadFactory implements ThreadFactory {
/**
* 记录当前是第几个线程池
*/
private static final AtomicInteger poolNum = new AtomicInteger(0);
/**
* 记录当前线程是线程池中的第几个线程
*/
private final AtomicInteger threadNum = new AtomicInteger(0);
/**
* 线程名格式
*/
private final String threadNameFormat;
public DefaultThreadFactory() {
threadNameFormat = "Pool-" + poolNum.incrementAndGet() + "-thread-";
}
@Override
public Thread creatThread(Runnable runnable) {
Thread thread = new Thread(runnable, threadNameFormat + threadNum.incrementAndGet());
return thread;
}
}
拒绝策略
接口
/**
* @Author Mr.wei
* @Date 2020/2/18 15:21
* @Description:拒绝策略的接口
*/
public interface CRejectPolicy {
/**
* 当任务满了之后的处理策略
* @param r
*/
public void reject(Runnable r);
}
实现类
/**
* @Author Mr.wei
* @Date 2020/2/18 18:14
* @Description:默认拒绝策略
*/
public class ExceptionRejectPolicy implements CRejectPolicy {
/**
* 当线程池中的线程和队列都满了,就打印消息
* @param r
*/
@Override
public void reject(Runnable r) {
System.out.println("队列已满!");
}
}
使用
/**
* @Author Mr.wei
* @Date 2020/2/18 18:13
* @Description:测试Pool
*/
public class TestPool {
public static void main(String[] args) {
CThreadPoolExecutor cThreadPoolExecutor = new CThreadPoolExecutor(5, 0, TimeUnit.SECONDS, new ArrayBlockingQueue(4), new ExceptionRejectPolicy());
for (int i = 0; i < 11; i++) {
cThreadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}