我们先不去看线程池原理,然后自己一步一步的分析,看看线程池都需要做哪些工作。
然后再一步一步的实现它,然后再去对比比人写好的线程池,然后看看差距在哪里。
# # 先分析为什么要用线程池
线程是任务调度的最小单位,其实可以这样理解,线程就是搬运的货车,将需要执行的字节码搬运给CPU去处理。
如果不使用线程池的话,有可能无限的去创建线程,系统的资源是有限的,一个服务器,如果一直创建线程,就能崩溃掉。阿里开发规范里边明确禁止在程序中显示的创建线程。
另外,即使系统资源够用,根据线程的生命周期,其实你创建的线程,在执行完以后似乎会销毁的。如果不用线程池,那就是帮我们搬运执行字节码的货车,只用用一次,用完一次就销毁,然后第二次用再创建一个,下次用还创建一个。线程的创建和销毁都是要消耗资源的,特备是大量的线程的创建更是。
所以我们用池的技术,老统一管理我们的资源,让线程统一维护在一个池子里边,从而做到更加安全的使用。
# # 用一个海底捞的例子,来说说线程池的工作原理
我们都知道,海底捞一般都是比较爆满的。但是海底捞的位子是有限的,如果你去的晚的话,可能就吃不上了。但是如果女朋友一定就要吃海底捞,别的不吃的话。就只能等等了。海底捞一般都会在门口放上一些椅子或者长凳,来吃的人,如果里边已经满了,就先在外边等一会儿,等里边的人吃完了,出来了,再进去。
而换成线程,那么需要搬运到CPU执行的任务,就是要吃火锅的人。
# # 一个简单的线程池都需要哪些呢
我们要一个长凳,来共消费者等待。这里我们只能使用阻塞队列。
我们需要提前创建一定数量的线程,创建好,这些线程就一直不休息了。就像生产者消费者模式一样,这些线程都作为消费者,是我前边讲到的货车,等待拉货。这些货车则组成车队,放在一个地方统一管理。
# # 动手实践
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
/**
* @author angus
* @create 2020-03-19 8:30
*/
public class MyThreadPool {
//1.存放想要被执行的任务
private BlockingQueue<Runnable> blockingQueue;
//2.存放固定数量的线程
private List<Thread> workers;
//线程池工作状态
private volatile boolean isWorking = true;
//3.创建线程
public static class Worker extends Thread{
private MyThreadPool pool;
public Worker(MyThreadPool pool){
this.pool = pool;
}
@Override
public void run(){
while (this.pool.isWorking || this.pool.blockingQueue.size() > 0){
Runnable task = null;
try {
if(this.pool.isWorking){
task = this.pool.blockingQueue.take();
}else {
task = this.pool.blockingQueue.poll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if(task != null){
task.run();
System.out.println("task:" + Thread.currentThread().getName() + "执行完毕");
}
}
}
}
public MyThreadPool(int taskSize, int poolSize){
if(taskSize <= 0 || poolSize <= 0){
throw new IllegalArgumentException("非法参数,taskSize 和 poolSize 必须大于0");
}
this.blockingQueue = new LinkedBlockingDeque<>(taskSize);
this.workers = new ArrayList<>();
for (int i = 0; i < poolSize; i++) {
Worker worker = new Worker(this);
worker.start();
workers.add(worker);
}
}
// 放入执行任务
public boolean submit(Runnable task){
if(isWorking){
return this.blockingQueue.offer(task);
}else {
return false;
}
}
// 关闭线程池
public void shutDown(){
this.isWorking = false;
for (Thread worker:workers){
if(worker.getState().equals(Thread.State.BLOCKED)){
worker.interrupt();
}
}
}
}
测试:
/**
* @author angus
* @create 2020-03-19 9:27
*/
public class MyThreadPoolDemo {
public static void main(String[] args) {
MyThreadPool pool = new MyThreadPool(3,3);
for (int i = 0; i < 3; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
System.out.println("##");
}
});
}
pool.shutDown();
}
}
标签:task,创建,线程,手写,public,pool,blockingQueue From: https://blog.51cto.com/u_15812686/5739735