jdk线程池的四种拒绝策略
Posted 好大的月亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdk线程池的四种拒绝策略相关的知识,希望对你有一定的参考价值。
概述
ThreadPoolExecutor
中有四种处理策略。
1.CallerRunsPolicy
:当最大线程数量上限 && 缓冲队列满了
,后续再有任务提交过来就让当前主线程去处理这个任务。
2. AbortPolicy
:当最大线程数量上限 && 缓冲队列满了
,后续再有任务提交过来就抛异常给主线程。
3. DiscardPolicy
:当最大线程数量上限 && 缓冲队列满了
,后续再有任务提交过来就将此任务直接丢弃。
4. DiscardOldestPolicy
:当最大线程数量上限 && 缓冲队列满了
,后续再有任务提交过来,会将缓冲队列队首的任务移除,然后在队末加入新任务。
代码demo
demo
中DiscardPolicy
策略由于是直接丢弃,没啥好展示,有兴趣可以改下策略查看打印结果
public class SendNoticeTask implements Runnable
Logger log = LoggerFactory.getLogger(SendNoticeTask.class);
private int count;
public SendNoticeTask(int count)
this.count = count;
@Override
public void run()
String name = Thread.currentThread().getName();
log.info( name + " start to send" + count);
try
Thread.sleep(10000);
catch (InterruptedException e)
e.printStackTrace();
log.info("finish " + name);
//有界队列
private static BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
//空队列,直接把任务交给消费线程,没有就直接创建
//Executors.newCachedThreadPool()采用的就是 coreSize = Integer.MAX_VALUE && synchronousQueue
private static BlockingQueue<Runnable> synchronousQueue = new SynchronousQueue<>();
/**
* 有界队列默认异常处理
* 当核心线程上线 && 缓冲队列满了,后续再有任务提交过来就抛异常给主线程
*/
public static void workQueueDefaultReject()
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 1000, TimeUnit.MICROSECONDS, workQueue);
for (int i = 0; i < 10; i++)
SendNoticeTask task = new SendNoticeTask(i);
threadPoolExecutor.execute(task);
log.info("主线程结束");
/**
* 有界队列拒绝策略 -> 由调用线程处理任务
* 当核心线程上线 && 缓冲队列满了,后续再有任务提交过来就让当前主线程去处理这个任务
*/
public static void callerRunsPolicy()
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2,
4,
1000,
TimeUnit.MICROSECONDS,
workQueue,
new ThreadPoolExecutor.CallerRunsPolicy()
);
for (int i = 0; i < 10; i++)
SendNoticeTask task = new SendNoticeTask(i);
threadPoolExecutor.execute(task);
log.info("主线程结束");
/**
* 有界队列拒绝策略 -> 由调用线程处理任务
* 当核心线程上线 && 缓冲队列满了,后续再有任务提交过来就,会将缓冲队列队首的任务移除,然后在队末加入新任务
*/
public static void discardOldestPolicy()
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2,
4,
1000,
TimeUnit.MICROSECONDS,
workQueue,
new ThreadPoolExecutor.DiscardOldestPolicy()
);
for (int i = 0; i < 10; i++)
SendNoticeTask task = new SendNoticeTask(i);
threadPoolExecutor.execute(task);
log.info("主线程结束");
/**
* synchronousQueuePolicy
* 直接将任务提交给消费线程->直接创建线程来消费
* Executors.newCachedThreadPool()采用的就是 coreSize = Integer.MAX_VALUE && synchronousQueue
*/
public static void synchronousQueuePolicy()
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2,
Integer.MAX_VALUE,
1000,
TimeUnit.MICROSECONDS,
synchronousQueue
);
for (int i = 0; i < 10; i++)
SendNoticeTask task = new SendNoticeTask(i);
threadPoolExecutor.execute(task);
log.info("主线程结束");
以上是关于jdk线程池的四种拒绝策略的主要内容,如果未能解决你的问题,请参考以下文章