import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.*;
/**
* @description: 测试使用线程池
*/
public class TestThreadPool {
public static void main(String[] args) {
//核心线程个数
int corePoolSize = 2;
//最大线程数量
int maximumPoolSize = 4;
//创建了超出核心线程个数的线程(临时线程)后,当该线程空闲下来可能会被销毁
//线程允许空闲时间(线程在空闲状态下,在允许空闲时间内不会销毁)
//TimeUnit表示允许线程空闲时间的单位
long keepAliveTime = 1L;
//等待队列
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1024);
//线程池饱和策略
RejectedExecutionHandler policy = new RejectedDiscardPolicy("taskId");
ExecutorService executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, queue, policy);
for (int i = 0; i < 100000; i++) {
executor.execute(new Worker());
}
//慎用shutdownNow(立即关闭线程池,不管队列中的任务是否执行完)
// executorService.shutdownNow();
//推荐使用shutdown去关闭线程池,这个方法会等待队列中的任务全部执行完才去关闭线程池
executor.shutdown();
}
}
class Worker implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "正在执行");
}
}
/**
* @description: 自定义饱和策略(中止策略也是默认策略)
*/
class RejectedAbortPolicy implements RejectedExecutionHandler {
/**
* 执行任务的标识
*/
private String taskId;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public RejectedAbortPolicy(String taskId) {
this.taskId = taskId;
}
/**
* @description: 使用该策略时在饱和时会抛出RejectedExecutionException(继承自RuntimeException),调用者可捕获该异常自行处理。
*/
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
throw new RejectedExecutionException(taskId +
" rejected from " +
executor.toString());
}
}
/**
* @description: 自定义饱和策略(抛弃策略)
*/
class RejectedDiscardPolicy implements RejectedExecutionHandler {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 执行任务的标识
*/
private String taskId;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public RejectedDiscardPolicy(String taskId) {
this.taskId = taskId;
}
/**
* @description: 不做任何处理直接抛弃任务
*/
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
//计划执行的大致任务数
String taskCount = String.valueOf(executor.getTaskCount());
//正在执行任务的大致线程数
String activeCount = String.valueOf(executor.getActiveCount());
//不处理使用抛弃策略
logger.error("RejectedDiscardPolicy.rejectedExecution, taskId :{}, task count: {}, active thread: {}", taskId,
taskCount, activeCount);
}
}
/**
* @description: 自定义饱和策略(抛弃旧任务策略)
*/
class RejectedDiscardOldestPolicy implements RejectedExecutionHandler {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 执行任务的标识
*/
private String taskId;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public RejectedDiscardOldestPolicy(String taskId) {
this.taskId = taskId;
}
/**
* @description: 先将阻塞队列中的当前任务抛弃,再尝试提交任务。如果此时阻塞队列使用PriorityBlockingQueue优先级队列,将会导致优先级最高的任务被抛弃,因此不建议将该种策略配合优先级队列使用。
*/
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if (!executor.isShutdown()) {
executor.getQueue().poll();
executor.execute(r);
}
logger.error("RejectedDiscardOldestPolicy.rejectedExecution,taskId:{}", taskId);
}
}
/**
* @description: 自定义饱和策略(调用者运行)
*/
class RejectedCallerRunsPolicy implements RejectedExecutionHandler {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 执行任务的标识
*/
private String taskId;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public RejectedCallerRunsPolicy(String taskId) {
this.taskId = taskId;
}
/**
* @description: 既不抛弃任务也不抛出异常,直接运行任务的run方法,换言之将任务回退给调用者来直接运行。
* 使用该策略时线程池饱和后将由调用线程池的主线程自己来执行任务,
* 因此在执行任务的这段时间里主线程无法再提交新任务,从而使线程池中工作线程有时间将正在处理的任务处理完成。
*/
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if (!executor.isShutdown()) {
r.run();
}
logger.warn("RejectedCallerRunsPolicy.rejectedExecution,taskId:{}", taskId);
}
}
juc - 线程池的使用
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 这是一篇 写的非常用心的 博文,这里是原文地址https://blog.csdn.net/l540675759/a...
- 1、简介:1.1 iOS有三种多线程编程的技术,分别是:1.、NSThread2、Cocoa NSOperatio...
- Executors为Executor,ExecutorService,ScheduledExecutorServi...