Java多线程高并发高级篇(三)--线程池核心中拒绝策略解密

在ThreadPoolExecutor的核心构造函数中,最后一个参数就是拒绝策略处理器。拒绝策略是等待任务队列已满,并且线程池处理不了任务时候,就需要一套处理机制,去解决这个问题(是抛弃还是怎么的)。

public ThreadPoolExecutor(int corePoolSize,  
                              int maximumPoolSize,  
                              long keepAliveTime,  
                              TimeUnit unit,  
                              BlockingQueue<Runnable> workQueue,  
                              ThreadFactory threadFactory,  
                              <strong>RejectedExecutionHandler handler</strong>) {  
        if (corePoolSize < 0 ||  
            maximumPoolSize <= 0 ||  
            maximumPoolSize < corePoolSize ||  
            keepAliveTime < 0)  
            throw new IllegalArgumentException();  
        if (workQueue == null || threadFactory == null || handler == null)  
            throw new NullPointerException();  
        this.corePoolSize = corePoolSize;  
        this.maximumPoolSize = maximumPoolSize;  
        this.workQueue = workQueue;  
        this.keepAliveTime = unit.toNanos(keepAliveTime);  
        this.threadFactory = threadFactory;  
        this.handler = handler;  
    }  

JDK内置了4种拒绝策略,分别是AbortPolicy,CallerRunsPolicy,DiscardOldestPolicy,DiscardPolicy。也可以自定义策略
在这里插入图片描述
在这里插入图片描述
我们介绍下这4中策略:

1、AbortPolicy

该策略会直接丢弃任务抛出运行时异常,阻止系统继续执行,处理方式简单粗暴。我们看源码:

Java代码

public static class AbortPolicy implements RejectedExecutionHandler {  
        /** 
         * Creates an <tt>AbortPolicy</tt>. 
         */  
        public AbortPolicy() { }  
  
        /** 
         * Always throws RejectedExecutionException. 
         * @param r the runnable task requested to be executed 
         * @param e the executor attempting to execute this task 
         * @throws RejectedExecutionException always. 
         */  
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
            <span style="color: #ff0000;">throw new RejectedExecutionException()</span>;  
        }  
    }  

在这里插入图片描述
2、CallerRunsPolicy
调用者运行策略
只要线程池不关闭,该策略直接在调用execute的线程中运行。这么做的弊端是调用者线程(任务提交线程)的性能下降。
使用此策略,如果添加到线程池失败,那么调用者线程会自己去执行该任务,不会等待线程池中的线程去执行。就像是个急脾气的人,我等不到别人来做这件事就干脆自己干。
看源码:

public static class CallerRunsPolicy implements RejectedExecutionHandler {  
        /** 
         * Creates a <tt>CallerRunsPolicy</tt>. 
         */  
        public CallerRunsPolicy() { }  
  
        /** 
         * Executes task r in the caller's thread, unless the executor 
         * has been shut down, in which case the task is discarded. 
         * @param r the runnable task requested to be executed 
         * @param e the executor attempting to execute this task 
         */  
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
            if (!e.isShutdown()) {  
                r.run();  
            }  
        }  
    }  

3、DiscardOldestPolicy

只要线程池不关闭,该策略将丢弃最老的一个任务(e.getQueue().poll())并且尝试将最新提交的线程存入队列,看源码:

public static class DiscardOldestPolicy implements RejectedExecutionHandler {  
        /** 
         * Creates a <tt>DiscardOldestPolicy</tt> for the given executor. 
         */  
        public DiscardOldestPolicy() { }  
  
        /** 
         * Obtains and ignores the next task that the executor 
         * would otherwise execute, if one is immediately available, 
         * and then retries execution of task r, unless the executor 
         * is shut down, in which case task r is instead discarded. 
         * @param r the runnable task requested to be executed 
         * @param e the executor attempting to execute this task 
         */  
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
            if (!e.isShutdown()) {  
                e.getQueue().poll();  
                   //再尝试入队
                e.execute(r);  
            }  
        }  
    } 

4、DiscardPolicy

该策略啥也不做,默默的丢弃任务(我从来没有来过。。。)

public static class DiscardPolicy implements RejectedExecutionHandler {  
        /** 
         * Creates a <tt>DiscardPolicy</tt>. 
         */  
        public DiscardPolicy() { }  
  
        /** 
         * Does nothing, which has the effect of discarding task r. 
         * @param r the runnable task requested to be executed 
         * @param e the executor attempting to execute this task 
         */  
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
        }  
    }  

https://blog.csdn.net/jgteng/article/details/54411423

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值