详解什么是Java线程池的拒绝策略?

 更新时间:2021年05月26日 15:21:12   作者:DavenPortChen.  
今天给大家总结一下线程池的拒绝策略,文中有非常详细的介绍及代码示例,对正在学习java的小伙伴们有很好地帮助,需要的朋友可以参考下

一、拒绝策略

(JDK提供了4种,另外也可以自定义拒绝策略,因此总共有5种。)
线程池中的线程已经用完了,无法继续为新任务服务,同时,等待队列也已经排满了,再也塞不下新任务了。这时候我们就需要拒绝策略机制合理的处理这个问题。

JDK 内置的拒绝策略如下:

1.AbortPolicy : 直接抛出异常,阻止系统正常运行。

2.CallerRunsPolicy : 只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。

3.DiscardPolicy : 该策略默默地丢弃无法处理的任务,不予任何处理。如果允许任务丢失,这是最好的一种方案。

4.DiscardOldestPolicy : 丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。

以上内置拒绝策略均实现了 RejectedExecutionHandler 接口,若以上策略仍无法满足实际需要,完全可以自己扩展 RejectedExecutionHandler 接口。

1.1 AbortPolicy(默认拒绝策略)

(也可以没有new ThreadPoolExecutor.AbortPolicy() 这个参数 ,隐式的默认拒绝策略)

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class ThreadDemo58 {
    public static void main(String[] args) {

        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, 5,
                0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(5),
                new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i < 11; i++) {
            int finalI = i;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("任务:" + finalI + ",线程名:" +
                            Thread.currentThread().getName());
                }
            });
        }
    }
}

1.2 CallerRunsPolicy(使用调用线程池的线程来执行任务 )

(即使用主线程来执行任务)

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class ThreadDemo59 {
    public static void main(String[] args) throws InterruptedException {

        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, 5,
                0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(5),
                new ThreadPoolExecutor.CallerRunsPolicy());
        for (int i = 0; i < 11; i++) {
            int finalI = i;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("任务:" + finalI + ",线程名:" +
                            Thread.currentThread().getName());
                }
            });
//            Thread.sleep(200);
        }

    }
}

1.3 DiscardPolicy (忽略新任务)

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;



public class ThreadDemo59 {
    public static void main(String[] args) throws InterruptedException {

        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, 5,
                0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(5),
                new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i < 11; i++) {
            int finalI = i;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("任务:" + finalI + ",线程名:" +
                            Thread.currentThread().getName());
                }
            });
        }
    }
}

1.4 DiscardOldestPolicy(忽略老任务)

(老任务指第一个进入阻塞队列里的)

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class ThreadDemo59 {
    public static void main(String[] args) throws InterruptedException {

        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, 5,
                0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(5),
                new ThreadPoolExecutor.DiscardOldestPolicy());
        for (int i = 0; i < 11; i++) {
            int finalI = i;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("任务:" + finalI + ",线程名:" +
                            Thread.currentThread().getName());
                }
            });
        }
    }
}

1.5 自定义拒绝策略

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class ThreadDemo60 {
    public static void main(String[] args) throws InterruptedException {

        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, 5,
                0, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(5),
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        // 自定义拒绝策略
                        System.out.println("执行了自定义拒绝策略");
                    }
                });
        for (int i = 0; i < 11; i++) {
            int finalI = i;
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("任务:" + finalI + ",线程名:" +
                            Thread.currentThread().getName());
                }
            });
        }
    }
}

到此这篇关于详解什么是线程池的拒绝策略?的文章就介绍到这了,更多相关线程池的拒绝策略内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于重定向RedirectAttributes的用法解析

    基于重定向RedirectAttributes的用法解析

    这篇文章主要介绍了基于重定向RedirectAttributes的用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 如何用java计算两个时间相差多少小时

    如何用java计算两个时间相差多少小时

    最近工作中遇到需要计算时间差,下面这篇文章主要给大家介绍了关于如何用java计算两个时间相差多少小时的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • Java中的两种for循环介绍

    Java中的两种for循环介绍

    在学习Hibernate的时候学习一种在Java当中的for循环,估计是以前学习的时候没有记住,忘记了在这里再写下笔记
    2012-10-10
  • SpringBoot中的@Conditional 注解的使用

    SpringBoot中的@Conditional 注解的使用

    @Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件的才给容器注册Bean,本文主要介绍了SpringBoot中的@Conditional 注解的使用
    2024-01-01
  • 正确结束Java线程的方法

    正确结束Java线程的方法

    线程的启动很简单,但用户可能随时取消任务,怎么样让跑起来的线程正确地结束,这是今天要讨论的话题。下面小编来和大家一起学习一下吧
    2019-05-05
  • java数据结构与算法之noDups去除重复项算法示例

    java数据结构与算法之noDups去除重复项算法示例

    这篇文章主要介绍了java数据结构与算法之noDups去除重复项算法实现技巧,程序代码非常简单,关键在于循环与判定,需要的朋友可以参考下
    2016-08-08
  • IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解决方案

    IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解决

    原来win10电脑上安装的是jdk8的版本,因某些原因,现在想换成jdk7的版本,修改环境变量后,在cmd中执行 [java -version]命令,显示的是7的版本,遇到这样的问题如何解决呢?下面小编给大家分享IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解决方案,一起看看吧
    2023-09-09
  • Java实现RSA加密工具类

    Java实现RSA加密工具类

    这篇文章主要介绍了Java如何实现RSA加密工具类,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2020-09-09
  • JavaEE idea的smart tomcat插件使用

    JavaEE idea的smart tomcat插件使用

    这篇文章主要介绍了JavaEE idea的smart tomcat插件使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-09-09
  • java计算自幂数和水仙花数

    java计算自幂数和水仙花数

    对于一个正整数而言,长度是n,如果它的各位上的数字的n次方之和正好等于它本身,那么我们称这样的数为自幂数,下面使用JAVA实现这个方法
    2014-03-03

最新评论