目录前言一、什么是线程池二、Java中的线程池1.execute()和submit()的区别①. execute()②. submit()2.自定义线程池①常见拒绝策略1. AbortPolicy2. CallerRunsPolicy3. DiscardPolicy4. DiscardOldestPolicy前言在我们之前学习多线程的时候使用线程往往使用的是new Thread()-{}.start()创建一个线程并启动这种方法虽然简单但是在实际场景并不会使用这种方法因为一旦任务很多频繁创建和销毁线程会带来很大的性能损耗甚至可能把系统拖垮。所以Java 提供了一个更合理的线程管理方案线程池Thread Pool。一、什么是线程池线程池顾名思义就是事先创建好一批线程统一放到一个池子里进行管理和复用。当有任务要执行时不着急创建一个新的线程而是首先来到线程池看一下有没有空闲的线程可以复用当任务执行完毕后线程不会销毁而是返回到线程池供下一次调用。核心思想预先创建一定数量的线程把待执行的任务放入任务队列由线程池中的线程不断从队列中取任务执行线程执行完成后不销毁继续复用通过统一策略控制线程数量和任务处理方式二、Java中的线程池Executors是一个工具类用来快速创建线程池。Executors.newFixedThreadPool(5); //创建一个有上限的线程池Executors.newCachedThreadPool(); //创建一个没有上限的线程池示例import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolDemo { public static void main(String[] args) { ExecutorService executorService Executors.newFixedThreadPool(3); for (int i 1; i 5; i) { int taskId i; executorService.execute(() - { System.out.println(任务 taskId 由线程 Thread.currentThread().getName() 执行); }); } executorService.shutdown(); } }运行效果线程池中最多有 3 个线程同时去处理 5 个任务。线程会被复用而不是每个任务都新建一个线程。1.execute()和submit()的区别在线程池中提交任务常见有两个方法execute()submit()①. execute()executorService.execute(() - { System.out.println(执行任务); });特点只能提交Runnable没有返回值更适合“只关心执行不关心结果”的任务②. submit()FutureInteger future executorService.submit(() - { return 100; });特点可以提交Runnable和Callable有返回值返回Future对象可以获取执行结果2.自定义线程池线程池常用的构造方法如下public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueRunnable workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler )①corePoolSize核心线程数线程池中长期保留的线程数量。当任务到来时线程池会优先创建线程直到线程数达到corePoolSize。②maximumPoolSize最大线程数线程池允许创建的最大线程数量。如果核心线程都在忙并且队列也已经满了线程池就会创建非核心线程直到总数达到maximumPoolSize。③keepAliveTime非核心线程空闲存活时间当线程池中的线程数大于核心线程数时多出来的那些非核心线程如果空闲时间超过keepAliveTime就会被回收。④unit时间单位keepAliveTime的时间单位。⑤workQueue任务队列当核心线程都在工作时新来的任务会被放到任务队列中等待执行。⑥threadFactory线程工厂用于创建线程。⑦handler拒绝策略当线程池无法继续接收新任务时会执行拒绝策略。①常见拒绝策略1. AbortPolicy默认策略。直接抛出异常RejectedExecutionException适合对任务丢失非常敏感的场景。2. CallerRunsPolicy由提交任务的线程自己执行该任务。这会让提交任务的线程“背压”减缓任务提交速度。3. DiscardPolicy直接丢弃任务不抛异常。适合允许部分任务丢失的场景但风险较大。4. DiscardOldestPolicy丢弃队列中最早的任务然后尝试提交当前任务。适合对“最新任务更重要”的场景。