原文网址:Java线程池--饱和策略(拒绝策略)的使用(有实例)_IT利刃出鞘的博客-CSDN博客
简介
本文用示例介绍Java线程池的饱和策略(拒绝策略)。
概述
Java线程池的饱和策略如下:
饱和策略 | 说明 |
ThreadPoolExecutor.AbortPolicy | 线程池默认的阻塞策略。 不执行此任务,而且抛出一个运行时异常(未检查的异常RejectedExecutionException)。 切记:ThreadPoolExecutor.execute需要try catch,否则程序会直接退出。 |
ThreadPoolExecutor.DiscardPolicy | 不执行此任务,而且不抛异常。(是个空方法) |
ThreadPoolExecutor.DiscardOldestPolicy | 从队列里删除最老的任务(头部的一个任务),并再次execute 此task。 |
ThreadPoolExecutor.CallerRunsPolicy | 让调用execute方法的线程执行此command,会阻塞入口。 这是个调节机制,既不抛弃任务也不抛出异常,而是将某些任务回退到调用者,让调用者所在的线程去执行。 |
用户自定义拒绝策略(最常用) | 实现RejectedExecutionHandler,并自己定义策略模式 |
实例
package concurrency.pool;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Created by li on 2016/7/2.
*/
public class SaturationPolicy {
/**
* 线程池工作队列已满时,在不同饱和策略下表现
* @param handler 线程池工作队列饱和策略
*/
public static void policy(RejectedExecutionHandler handler){
//基本线程2个,最大线程数为3,工作队列容量为5
ThreadPoolExecutor exec = new ThreadPoolExecutor(2,3,0, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(5));
if (handler != null){
exec.setRejectedExecutionHandler(handler);//设置饱和策略
}
for (int i = 0; i < 10; i++) {
exec.submit(new Task());//提交任务
}
exec.shutdown();
}
//自定义任务
static class Task implements Runnable {
private static int count = 0;
private int id = 0;//任务标识
public Task() {
id = ++count;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(3);//休眠3秒
} catch (InterruptedException e) {
System.err.println("线程被中断" + e.getMessage());
}
System.out.println(" 任务:" + id + "\t 工作线程: "+ Thread.currentThread().getName() + " 执行完毕");
}
}
public static void main(String[] args) {
// policy(new ThreadPoolExecutor.AbortPolicy());
// policy((new ThreadPoolExecutor.CallerRunsPolicy()));
// policy(new ThreadPoolExecutor.DiscardPolicy());
// policy(new ThreadPoolExecutor.DiscardOldestPolicy());
}
}
1. Abort策略:默认策略。
新任务提交时直接抛出未检查的异常RejectedExecutionException,该异常可由调用者捕获。
在主函数中添加如下代码:
policy(new ThreadPoolExecutor.AbortPolicy());
运行结果:
程序抛出了RejectedExecutionException,并且一共运行了8个任务(线程池开始能运行3个任务,工作队列中存储5个队列)。当工作队列满了的时候,直接抛出了异常,而且JVM一直不退出(我现在也不知道什么原因)。我们可以看到执行任务的线程全是线程池中的线程。
上边是文章的部分内容,为便于维护,全文已迁移到此网址:Java线程池-饱和策略(拒绝策略)的使用(有实例) - 自学精灵