手写线程池

 我们先不去看线程池原理,然后自己一步一步的分析,看看线程池都需要做哪些工作。

 然后再一步一步的实现它,然后再去对比比人写好的线程池,然后看看差距在哪里。

 

# # 先分析为什么要用线程池

  线程是任务调度的最小单位,其实可以这样理解,线程就是搬运的货车,将需要执行的字节码搬运给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 blockingQueue;

	//2.存放固定数量的线程
	private List 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();
	}
}

 

你可能感兴趣的:(多线程实战)