Java 之ThreadPoolExecutor.RejectedExecutionHandler

    xiaoxiao2021-08-20  121

    ThreadPoolExecutor.AbortPolicy()抛出java.util.concurrent.RejectedExecutionException异常 终止策略是默认的饱和策略; ThreadPoolExecutor.CallerRunsPolicy()当抛出RejectedExecutionException异常时,会调rejectedExecution方法 调用者运行策略实现了一种调节机制,该策略既不会抛弃任务也不会爆出异常,而是将任务退回给调用者,从而降低新任务的流量 ThreadPoolExecutor.DiscardOldestPolicy()抛弃旧的任务;当新提交的任务无法保存到队列中等待执行时将抛弃最旧的任务,然后尝试提交新任务。如果等待队列是一个优先级队列,抛弃最旧的策略将导致抛弃优先级最高的任务,因此AbortPolicy最好不要和优先级队列一起使用。ThreadPoolExecutor.DiscardPolicy()抛弃当前的任务

     

    Java代码   /**   *返回给调用者的饱和策略   * @author zhangwei_david   * @version $Id: CallerRunsTestClient.java, v 0.1 2014年11月13日 下午3:14:58 zhangwei_david Exp $   */   public class CallerRunsTestClient {          /**       *       * @param args       */       public static void main(String[] args) {           //等待队列           final LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(5);                      ThreadPoolExecutor executor = new ThreadPoolExecutor(352, TimeUnit.SECONDS, queue);              executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());              for (int i = 0; i < 15; i++) {               executor.execute(new Runnable() {                      public void run() {                       System.out.println("run-" + Thread.currentThread().getName() + " queue:"                                          + queue.size());                       try {                           TimeUnit.SECONDS.sleep(20);                       } catch (InterruptedException e) {                           //logger.error("", e);                       }                   }               });           }       }      }  

     运行的结果是:可以在日志中看有两次是在主线程中运行的

    Java代码   run-pool-1-thread-1 queue:5   run-pool-1-thread-2 queue:5   run-pool-1-thread-3 queue:5   run-main queue:5   run-pool-1-thread-4 queue:5   run-pool-1-thread-5 queue:5   run-pool-1-thread-1 queue:4   run-pool-1-thread-3 queue:2   run-pool-1-thread-2 queue:3   run-main queue:5   run-pool-1-thread-5 queue:4   run-pool-1-thread-4 queue:3   run-pool-1-thread-2 queue:1   run-pool-1-thread-1 queue:1   run-pool-1-thread-3 queue:0  

     终止饱和策略是,当提交的任务无法进入等待队列且线程池中创建的线程数量已经达到了最大线程数量的限制,则会拒绝新提交的任务。

    Java代码   /**   *终止饱和策略   * @author zhangwei_david   * @version $Id: AbortTestClient.java, v 0.1 2014年11月13日 下午3:03:47 zhangwei_david Exp $   */   public class AbortTestClient {          public static void main(String[] args) {              final ThreadPoolExecutor executor = new ThreadPoolExecutor(132, TimeUnit.SECONDS,               new LinkedBlockingQueue<Runnable>(5));              executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());              executor.setThreadFactory(new MyThreadFactory("Test"));              for (int i = 0; i < 10; i++) {               try {                   executor.execute(new Runnable() {                          public void run() {                           //doNothing                       }                   });               } catch (RejectedExecutionException e) {                   System.out.println("第" + i + "次提交线程被拒绝!  当前活动线程数:" + executor.getActiveCount()                       + " 队列长度:" + executor.getQueue().size());               }           }       }   }  

     运行的结果:

    Java代码   8次提交线程被拒绝!  当前活动线程数:3 队列长度:5   9次提交线程被拒绝!  当前活动线程数:3 队列长度:5   一月 212015 9:11:03 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run   信息: Created Test-2   一月 212015 9:11:03 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run   信息: Created Test-1   一月 212015 9:11:03 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run   信息: Created Test-3   一月 212015 9:11:05 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run   信息: Exiting Test-3   一月 212015 9:11:05 下午 com.cathy.demo.concurrency.executor.threadFactory.MyAppThread run   信息: Exiting Test-1  

    DiscardPolicy 是抛弃当前任务

     

    Java代码   /**   *   * @author zhangwei_david   * @version $Id: DiscardTestClient.java, v 0.1 2014年11月13日 下午3:16:28 zhangwei_david Exp $   */   public class DiscardTestClient {          /**       *       * @param args       */       public static void main(String[] args) {           final ThreadPoolExecutor executor = new ThreadPoolExecutor(132, TimeUnit.SECONDS,               new LinkedBlockingQueue<Runnable>(5));              executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());              for (int i = 0; i < 10; i++) {               System.out.println(MessageFormat.format("第{0}次提交任务,当前等待队列长度{1}", i, executor.getQueue()                   .size()));               executor.execute(new Runnable() {                      public void run() {                       System.out.println(Thread.currentThread().getName());                       try {                           TimeUnit.SECONDS.sleep(10);                       } catch (InterruptedException e) {                           //logger.error("", e);                       }                   }               });              }           executor.shutdown();          }      }    运行结果是: Java代码   0次提交任务,当前等待队列长度0   1次提交任务,当前等待队列长度0   pool-1-thread-1   2次提交任务,当前等待队列长度1   3次提交任务,当前等待队列长度2   4次提交任务,当前等待队列长度3   5次提交任务,当前等待队列长度4   6次提交任务,当前等待队列长度5   pool-1-thread-2   7次提交任务,当前等待队列长度5   pool-1-thread-3   8次提交任务,当前等待队列长度5   9次提交任务,当前等待队列长度5   pool-1-thread-1   pool-1-thread-2   pool-1-thread-3   pool-1-thread-1   pool-1-thread-3    通过结果可以发现,提交了10个任务最终只有8个任务被执行!其中有两次被抛弃了! DiscardOldestPolicy :抛弃最旧的任务

     

     

     

     

    Java代码   /**   *   * @author zhangwei_david   * @version $Id: DiscardOldestTest.java, v 0.1 2015年1月22日 上午9:42:21 zhangwei_david Exp $   */   public class DiscardOldestTest {          /**       *       * @param args       */       public static void main(String[] args) {           final ThreadPoolExecutor executor = new ThreadPoolExecutor(132, TimeUnit.SECONDS,               new LinkedBlockingQueue<Runnable>(5));              executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());              for (int i = 0; i < 10; i++) {               System.out.println(MessageFormat.format("第{0}次提交任务,当前等待队列长度{1}", i, executor.getQueue()                   .size()));               executor.execute(new MyTask(String.valueOf(i)));              }           executor.shutdown();          }          public static class MyTask implements Runnable {              private String name;              /**           * @see java.lang.Runnable#run()           */           public void run() {               System.out.println(name);               try {                   TimeUnit.SECONDS.sleep(10);               } catch (InterruptedException e) {                   //logger.error("", e);               }           }              public MyTask(String name) {               super();               this.name = name;           }          }      }    

     

     

     

    Java代码   0次提交任务,当前等待队列长度0   0   1次提交任务,当前等待队列长度0   2次提交任务,当前等待队列长度1   3次提交任务,当前等待队列长度2   4次提交任务,当前等待队列长度3   5次提交任务,当前等待队列长度4   6次提交任务,当前等待队列长度5   7次提交任务,当前等待队列长度5   8次提交任务,当前等待队列长度5   9次提交任务,当前等待队列长度5   6   7   3   4   5   8   9    发现第二次和第三次提交的任务被抛弃了!

     

    转载请注明原文地址: https://ju.6miu.com/read-676722.html

    最新回复(0)