详解什么是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());
                }
            });
        }
    }
}

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

相关文章

  • Spring AI TikaDocumentReader详解

    Spring AI TikaDocumentReader详解

    TikaDocumentReader是SpringAI中用于从多种格式文档中提取文本内容的组件,支持PDF、DOC/DOCX、PPT/PPTX和HTML等格式,它在构建知识库、文档处理和数据清洗等任务中非常有用
    2025-01-01
  • Springmvc ResponseBody响应json数据实现过程

    Springmvc ResponseBody响应json数据实现过程

    这篇文章主要介绍了Springmvc ResponseBody响应json数据实现过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • SpringBoot发送异步邮件流程与实现详解

    SpringBoot发送异步邮件流程与实现详解

    这篇文章主要介绍了SpringBoot发送异步邮件流程与实现详解,Servlet阶段邮件发送非常的复杂,如果现代化的Java开发是那个样子该有多糟糕,现在SpringBoot中集成好了邮件发送的东西,而且操作十分简单容易上手,需要的朋友可以参考下
    2024-01-01
  • RabbitMQ 避免消息重复消费的方法

    RabbitMQ 避免消息重复消费的方法

    消费者端实现幂等性,意味着消息永远不会消费多次,即使收到了多条一样的消息,这篇文章给大家分享RabbitMQ 避免消息重复消费的方法,感兴趣的朋友一起看看吧
    2024-03-03
  • 一次踩坑记录 @valid注解不生效 排查过程

    一次踩坑记录 @valid注解不生效 排查过程

    这篇文章主要介绍了一次踩坑记录 @valid注解不生效 排查过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • apache commons工具集代码详解

    apache commons工具集代码详解

    这篇文章主要介绍了apache commons工具集代码详解,具有一定借鉴价值,需要的朋友可以参考下
    2017-12-12
  • java使用动态代理来实现AOP(日志记录)的实例代码

    java使用动态代理来实现AOP(日志记录)的实例代码

    AOP(面向方面)的思想,就是把项目共同的那部分功能分离开来,比如日志记录,避免在业务逻辑里面夹杂着跟业务逻辑无关的代码
    2013-09-09
  • java集合模拟实现斗地主洗牌和发牌

    java集合模拟实现斗地主洗牌和发牌

    这篇文章主要为大家详细介绍了java集合模拟实现斗地主洗牌和发牌,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • java经典问题:连个字符串互为回环变位

    java经典问题:连个字符串互为回环变位

    连个字符串互为回环变位经常出现在java程序员面试中,这个是考验程序员的解题思路和方法的最经典的一题,小编为大家详细分析一下,一起来学习吧。
    2017-11-11
  • Java修改Integer变量值遇到的问题及解决

    Java修改Integer变量值遇到的问题及解决

    这篇文章主要介绍了Java修改Integer变量值遇到的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论