public class SimpleExecutorImpl { //默认可用状态 private volatile boolean RUNNING = true; private volatile boolean shutdown = false; //Task Queue:任务队列,FIFO,阻塞 private static BlockingQueue<Runnable> queue = null; //Worker Queue private static BlockingQueue<Worker> workers = new LinkedBlockingQueue<>(); //最大线程数 private int poolSize = 0; //核心线程数 private int coreSize = 0; public SimpleExecutorImpl(int poolSize) { this.poolSize = poolSize; queue = new LinkedBlockingQueue<>(poolSize); } public void execute(Runnable runnable) { if(runnable == null) { throw new NullPointerException("Task is null!"); } if(coreSize <= poolSize) { createWorker(runnable); } else { try { queue.put(runnable); } catch (InterruptedException e) { e.printStackTrace(); } } } public void createWorker(Runnable runnable) { coreSize++; Worker worker = new Worker(runnable); workers.add(worker); try { worker.start(); } catch (Exception e) { e.printStackTrace(); } } public synchronized void shutDown() { RUNNING = false; if(!workers.isEmpty()){ for (Worker worker : workers){ worker.isInterruptedIfAble(worker); } } shutdown = true; Thread.currentThread().interrupt(); } class Worker extends Thread { public Worker(Runnable runnable) { queue.offer(runnable); } @Override public void run() { //使用while循环实现线程不断获取任务 while(true && RUNNING) { if(shutdown) { Thread.currentThread().interrupt(); } try { getTask().run(); }catch (Exception e) { e.printStackTrace(); } } } private Runnable getTask() throws InterruptedException { return queue.take(); } public void isInterruptedIfAble(Thread thread) { System.out.println(thread.getName() + " is interrupted!"); thread.interrupt(); try { workers.remove(thread); }catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { SimpleExecutorImpl executor = new SimpleExecutorImpl(5); for(int i = 0; i < 20; i++) { executor.execute(new Runnable() { @Override public void run() { System.out.println("线程" + Thread.currentThread().getName() + " is working!"); } }); } executor.shutDown(); } }
为什么要使用线程池呢?
1.创建和销毁线程的开销很大
2.新的请求过来,如果直接使用已经创建好的线程,响应会更好
3.线程池会限制线程创建的数量,防止资源(主要是内存)耗尽
如何实现的最简单的线程池呢?
需要明白线程池的作用就是将生产任务和执行任务解耦,是一种弹性设计。线程池的核心就是存储任务的任务队列和执行任务的线程队列,上边就是线程池的简单实现,没有考虑线程安全。