jdk线程池的四种拒绝策略

Posted 好大的月亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdk线程池的四种拒绝策略相关的知识,希望对你有一定的参考价值。

概述

ThreadPoolExecutor中有四种处理策略。

1.CallerRunsPolicy:当最大线程数量上限 && 缓冲队列满了,后续再有任务提交过来就让当前主线程去处理这个任务。
2. AbortPolicy:当最大线程数量上限 && 缓冲队列满了,后续再有任务提交过来就抛异常给主线程。
3. DiscardPolicy:当最大线程数量上限 && 缓冲队列满了,后续再有任务提交过来就将此任务直接丢弃。
4. DiscardOldestPolicy:当最大线程数量上限 && 缓冲队列满了,后续再有任务提交过来,会将缓冲队列队首的任务移除,然后在队末加入新任务。

代码demo

demoDiscardPolicy策略由于是直接丢弃,没啥好展示,有兴趣可以改下策略查看打印结果

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线程池的四种拒绝策略的主要内容,如果未能解决你的问题,请参考以下文章

线程池的拒绝策略示例

Java线程池中的四种拒绝策略

JDK线程池的拒绝策略

线程池基本使用详解

JAVA线程池的拒绝策略有哪几种?

线程池(详解):三大方法七大参数四种拒绝策略