线程池的工作原理
一、任务在线程池中是如何被执行的
二、线程池的拒绝策略
1) 默认的策略是AbortPolicy 当大于最大线程数后直接抛出异常
代码实现:
/** * 核心线程数1 最大线程2 任务队列大小2 采用AbortPolicy * 运行结果 * 0 * 3 * 1 * 2 * Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.lwd.thread.MyRunable@77afea7d rejected from java.util.concurrent.ThreadPoolExecutor@5f8ed237[Running, pool size = 2, active threads = 0, queued tasks = 0, completed tasks = 4] * at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063) * at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830) * at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379) * 分析: 1.当第一个任务0进入线程池,没有任务执行,创建一个线程去执行线程任务 * 2.当的第二个任务3进入线程池,由于核心线程已经满了将3加入队列 * 3.第三个任务1 也加入队列中 * 4.第四个任务2到了进入,判断当前任务队列已经满了,但是小于最大线程池数,那么创建一个新的线程来执行 * 5.后续的任务进入后,发现有都满了 那么直接抛出异常启动了拒绝策略AbortPolicy * * */ public static void abortPolicy(){ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2),new ThreadPoolExecutor.AbortPolicy()); for (int i = 0; i < 6; i++) { MyRunable myRunable = new MyRunable(i); threadPoolExecutor.execute(myRunable); } }
实现方式:
/** * Always throws RejectedExecutionException. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task * @throws RejectedExecutionException always */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); }
2)CallerRunsPolicy 当没有可执行任务的线程,持有当前线程池的线程执行线程任务 会造成主线程阻塞
/** * 线程池无法执行,新的任务由持有当前线程池的线程运行,缺点会造成主线程阻塞 * */ public static void callerRunsPolicy(){ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2),new ThreadPoolExecutor.CallerRunsPolicy()); for (int i = 0; i < 6; i++) { MyRunable myRunable = new MyRunable(i); threadPoolExecutor.execute(myRunable); } }
3)自定义拒绝策略
实现RejectedExecutionHandler接口 重写rejectedExecution方法 我内部采用的是创建新的线程执行线程任务
package com.lwd.thread; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; /** * 自定义的拒绝策略 */ public class MyRejectedExecutionHandle implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { new Thread(r,"我是新线程").start(); } }
使用自定义策略
/** * 采用自定义的拒绝策略 * 运行结果: * 线程任务执行===========4 * 线程任务执行===========5 * 线程任务执行===========0 * 线程任务执行===========3 * 线程任务执行===========1 * 线程任务执行===========2 * */ public static void myRejectedExecutionHandle(){ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2),new MyRejectedExecutionHandle()); for (int i = 0; i < 6; i++) { MyRunable myRunable = new MyRunable(i); threadPoolExecutor.execute(myRunable); } }