• 线程池的4种拒绝策略


    线程池的拒绝策略

    线程池中有三个重要参数,影响拒绝策略

    • corePoolSize 核心线程数 ,也是最小线程数
    • workQueue 阻塞队列
    • maximumPoolSize 最大线程数

    当提交任务数大于corePoolSize 的时候,会优先将任务放到workQueue阻塞队列中。当阻塞队列饱和后,会扩充线程池中线程数到maximumPoolSize最大线程数。此时,多余的任务,则会触发线程数的拒绝策略。

    拒绝策略

    拒绝策略提供了顶级接口RejectedExecutionHander,其中方法rejectedExecution即定制具体的拒绝策略的执行逻辑。
    jdk默认的4种拒绝策略

    • AbortPolicy (线程池默认的拒绝策略)
      丢弃任务,并抛出拒绝执行RejectedExecutionException 异常信息。必须处理好抛出的异常,否则会打断当前的执行流程,影响后续的执行任务。
    • CallerRunsPolicy
      当触发拒绝策略,只要线程池没有关闭的话,则使用调用线程直接运行任务。一般并发比较小,性能要求不高,不允许失败。但是由于调用者自己运行任务,如果任务提交速度过快,可能导致程序阻塞,性能效率会严重下降。
    • DiscardPolicy
      直接丢弃,什么措施都没有。
    • DiscardOldestPolicy
      当触发拒绝策略,只要线程池没有关闭的话,丢失阻塞队列workQueue中最老的一个任务,并将新任务加入到队列。

    使用AbortPolicy策略

    import java.util.concurrent.BlockingDeque;
    import java.util.concurrent.LinkedBlockingDeque;
    import java.util.concurrent.RejectedExecutionHandler;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class AbortPolicyTest {
    	
    	public static void main(String[] args) {
    		AtomicInteger count=new AtomicInteger(0);
    		int corePoolSize = 2, maximumPoolSize = 5, keepAliveTime = 5;
    		BlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<>(10);
    		RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
    		ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
    				TimeUnit.SECONDS, workQueue, handler);
    
    		for (int i = 0; i < 100; i++) {
    			executor.execute(new Thread(() -> {
    				int t=count.incrementAndGet();
    				System.out.println(t+"   线程名:" + Thread.currentThread().getName() + " running ------");
    			}));
    		}
    
    		executor.shutdown();
    	}
    }
    

    executor.execute()提交任务执行,由于会抛出RuntimeException,如果没有try catch处理异常信息的话,会中断调用者的处理流程,后续任务得不到执行。
    在这里插入图片描述

    Java提供的四种拒绝策略

    AbortPolicy策略

    RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();		
    

    CallerRunsPolicy策略

    RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();		
    

    在控制台可以看到,会显示main is running, 体现出调用线程也在处理任务。
    在这里插入图片描述

    DiscardPolicy策略

    RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
    

    在控制台可以看到,实际被执行的任务没有100条,其它未被执行的任务被直接抛弃了。
    在这里插入图片描述

    DiscardOldestPolicy策略

    RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
    

    在控制台可以看到,大量的任务被丢弃不能被执行。
    在这里插入图片描述

    默认拒绝策略

    四种拒绝策略是独立无关的处理策略,使用何种拒绝策略执行线程,需要结合实际业务。
    通常实际开发中,我们使用ExecutorService,而它的默认拒绝策略是AbortPolicy
    在这里插入图片描述

  • 相关阅读:
    【nlp】1.3 文本数据分析(标签数量分布、句子长度分布、词频统计与关键词词云)
    金融网站如何做好安全防护措施?
    Win10C盘满了怎么清理?如何清理电脑C盘?
    docker方式安装redis-自定义redis配置文件
    Matlab绘制散点的95%置信区间图
    jQuery 事件方法大全-超全的总结
    Exchange Office 365邮箱报表
    【华为OD题库-033】经典屏保-java
    【考研数学】高等数学第七模块 —— 曲线积分与曲面积分 | 2. 对坐标的曲线积分(第二类积分)
    Morris遍历
  • 原文地址:https://blog.csdn.net/u011628753/article/details/127091060