线程池
作用
1)可以根据具体的应用场景和系统的承受能力,手动或自动的设置工作线程的数量,减少资源的浪费,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)
2)减少了创建线程和销毁线程的次数,提高了线程的可复用性
框架图
Executors类
Executor子接口及其子接口ExecutorService、子类AbstractExecutorService、底层实现类ThreadPoolExecutor
线程池的创建与使用
1)先创建一个线程池,主要有以下四种方式
//一池1个工作线程,类似于一个银行有N个受理窗口 ExecutorService threadPool = Executors.newSingleThreadExecutor(); //一池5个工作线程,类似于一个银行有5个受理窗口 ExecutorService threadPool = Executors.newFixedThreadPool(5); //一池N个工作线程,类似于一个银行有N个受理窗口 ExecutorService threadPool = Executors.newCachedThreadPool(); //创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求 ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(3);
2)调用线程池的execute()方法
public class MyThreadPoolDemo { public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(5); try { //模拟有20个顾客来银行办理业务,目前池子里有5个工作人员提供服务 for (int i = 1; i <= 20; i++) { threadPool.execute(() -> { System.out.println(Thread.currentThread().getName() + "\t 办理业务"); try{ TimeUnit.SECONDS.sleep(3); } catch(InterruptedException e){ e.printStackTrace(); } }); try{ TimeUnit.SECONDS.sleep(1); } catch(InterruptedException e){ e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } finally { threadPool.shutdown(); } } }
工作机制
将任务派发给线程池时,会出现以下几种情况
1)核心线程池未满,创建一个新的线程执行任务。
2)如果核心线程池已满,工作队列未满,将线程存储在工作队列。
3)如果工作队列已满,线程数小于最大线程数就创建一个新线程处理任务。
4)如果超过大小线程数,按照拒绝策略来处理任务。
线程池7大参数
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.acc = System.getSecurityManager() == null ? null : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
1)corePoolSize:指定了线程池中的线程数量,它的数量决定了添加的任务是开辟新的线程去执行,还是放到workQueue任务队列中去;
2)maximumPoolSize:指定了线程池中的最大线程数量,这个参数会根据你使用的workQueue任务队列的类型,决定线程池会开辟的最大线程数量;
3)keepAliveTime:当线程池中空闲线程数量超过corePoolSize时,多余的线程会在多长时间内被销毁;
4)unit:keepAliveTime的单位
5)workQueue:任务队列,被添加到线程池中,但尚未被执行的任务;它一般分为直接提交队列、有界任务队列、无界任务队列、优先任务队列几种;
6)threadFactory:线程工厂,用于创建线程,一般用默认即可;
7)handler:拒绝策略;当任务太多来不及处理时,如何拒绝任务;
拒绝策略
阿里巴巴开发手册对线程池的使用
参考链接:https://blog.csdn.net/qq_31753145/article/details/50899119