以鄙人对线程池的浅显了解,其基本原理是:创建线程,执行任务,任务结束后不让线程销毁,继续接受并处理队列中的其他任务。
其核心点就是让线程不自动销毁,并可以接收其他任务执行。我就以此理论来写一个简易版的线程池。
package edu.threads;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author dell
*/
public class ThreadPool {
/** 空闲线程数量 **/
AtomicInteger free = new AtomicInteger(0);
private int maxSize;
BlockingQueue<Runnable> taskQueue = new ArrayBlockingQueue<>(13);
public ThreadPool(int maxSize) {
if (maxSize < 0) {
throw new RuntimeException("核心线程数量不能小于0");
}
this.maxSize = maxSize;
}
public void haveFreeTime() {
this.free.addAndGet(1);
}
public Runnable getTask() {
Runnable runnable = taskQueue.poll();
if (runnable != null) {
free.addAndGet(-1);
return runnable;
}
return null;
}
void execute(Runnable runnable) throws InterruptedException {
if (this.free.get() < maxSize) {
Thread thread = new Thread(new Worker(this));
thread.start();
free.addAndGet(1);
}
this.taskQueue.add(runnable);
}
public static void main(String[] args) throws InterruptedException {
ThreadPool threadPool = new ThreadPool(5);
for (int i = 0; i < 13; i++) {
int finalI = i;
threadPool.execute(() -> {
System.out.println("第" + finalI + "个任务,先阻塞2秒[" + Thread.currentThread().getName() + "]");
try {
Thread.sleep(2000);
System.out.println("第" + finalI + "个任务结束[" + Thread.currentThread().getName() + "]");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
}
class Worker implements Runnable {
private ThreadPool pool;
public Worker(ThreadPool pool) {
this.pool = pool;
}
@Override
public void run() {
Runnable task;
//核心:让线程一直死循环,循环内部去获取任务,有任务就执行,没任务继续循环
while (true) {
if ((task = pool.getTask()) != null) {
//执行任务
task.run();
//任务执行完之后就标注闲下来
this.pool.haveFreeTime();
}
}
}
}