返回顶部
首页 > 资讯 > 后端开发 > Python >详解Java ThreadPoolExecutor的拒绝策略
  • 164
分享到

详解Java ThreadPoolExecutor的拒绝策略

2024-04-02 19:04:59 164人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录背景线程池基本原理线程池拒绝策略AbortPolicyCallerRunsPolicyDiscardPolicy示例执行结果DiscardOldestPolicy示例说明自定义拒

背景

线程池的技术在项目中使用广泛,线程池提供了四种拒绝策略,大家是否了解这四种拒绝的策略呢?本文将详细的讲解ThreadPoolExecutor的四种拒绝策略,以及相关的注意事项。

线程池基本原理

线程池的原理如下图:

说明:

  • 当前运行的线程少于corePoolSize,则创建新线程来执行任务。
  • 运行的线程等于或多于corePoolSize,则将任务添加到队列中。
  • 当任务队列已满,则在非corePool中创建新的线程来处理任务。
  • 创建新线程将使当前运行的线程超出maximumPoolSize,任务将被拒绝,并调用RejectedExecutionHandler.rejectedExecution()方法。

线程池拒绝策略

线程池为我们提供了四种拒绝策略分别是:CallerRunsPolicy,AbortPolicy,DiscardPolicy,DiscardOldestPolicy

AbortPolicy

ThreadPoolExecutor中默认的拒绝策略就是AbortPolicy直接抛出异常,具体实现如下

public static class AbortPolicy implements RejectedExecutionHandler {
    public AbortPolicy() { }
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        throw new RejectedExecutionException("Task " + r.toString() +
                                             " rejected from " +
                                             e.toString());
    }
}

说明:这种策略非常简单粗暴,直接抛出RejectedExecutionException异常,也不会执行后续的任务。

示例说明:

public class ThreadPoolTest
{
    public static void main(String[] args)
    {
        ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                2,
                5,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(1),
                new ThreadPoolExecutor.AbortPolicy());
        
        //异步执行
        for(int i=0; i<10;i++)
        {
          System.out.println("添加第"+i+"个任务");
          threadPoolExecutor.execute(new TestThread("线程"+i));
        }        
    }
}

public class TestThread implements Runnable
{
    private String name;
    public TestThread(String name){
        this.name=name;
    }
    
    @Override
    public void run()
    {
        try
        {
            Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        System.out.println("thread name:"+Thread.currentThread().getName()+",执行:"+name);
    }
}

执行结果:

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.skywares.fw.juc.thread.TestThread@55f96302 rejected from java.util.concurrent.ThreadPoolExecutor@3D4eac69[Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
    at com.skywares.fw.juc.thread.ThreadPoolTest.main(ThreadPoolTest.java:26)
thread name:pool-1-thread-5,执行:线程5
thread name:pool-1-thread-2,执行:线程1
thread name:pool-1-thread-4,执行:线程4
thread name:pool-1-thread-3,执行:线程3
thread name:pool-1-thread-1,执行:线程0
thread name:pool-1-thread-5,执行:线程2

从执行结果我们得知,采用AbortPolicy策略当任务执行到第七个任务时会直接报错,导致后续的业务逻辑不会执行。

CallerRunsPolicy

CallerRunsPolicy在任务被拒绝添加后,会用调用execute函数的上层线程去执行被拒绝的任务。

相关示例

public class ThreadPoolTest
{
    public static void main(String[] args)
    {
        ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                2,
                5,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(1),
                new ThreadPoolExecutor.CallerRunsPolicy());
        
        //异步执行
        for(int i=0; i<10;i++)
        {
          System.out.println("添加第"+i+"个任务");
          threadPoolExecutor.execute(new TestThread("线程"+i));
        }
    }
}

执行结果:

添加第0个任务
添加第1个任务
添加第2个任务
添加第3个任务
添加第4个任务
添加第5个任务
添加第6个任务
thread name:main,执行:线程6
thread name:pool-1-thread-3,执行:线程3
thread name:pool-1-thread-1,执行:线程0
thread name:pool-1-thread-4,执行:线程4
thread name:pool-1-thread-2,执行:线程1
thread name:pool-1-thread-5,执行:线程5
添加第7个任务
添加第8个任务
thread name:main,执行:线程8
thread name:pool-1-thread-1,执行:线程7
thread name:pool-1-thread-3,执行:线程2
添加第9个任务
thread name:pool-1-thread-1,执行:线程9

从执行的结果我们可以得知,当执行到第7个任务时,由于线程池拒绝策略,此任务由主线程来执行,当线程池有空闲时,才继续执行其他的任务。所以此策略可能会阻塞主线程。

DiscardPolicy

这种拒绝策略比较简单,线程池拒绝的任务直接抛弃,不会抛异常也不会执行

示例

修改上述的代码,将拒绝策略修改为DiscardPolicy

 ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                2,
                5,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(1),
                new ThreadPoolExecutor.CallerRunsPolicy());

执行结果

invoke dealStock success
GoodsId:手机
thread name:pool-1-thread-1,执行:线程0
thread name:pool-1-thread-4,执行:线程4
thread name:pool-1-thread-5,执行:线程5
thread name:pool-1-thread-3,执行:线程3
thread name:pool-1-thread-2,执行:线程1
thread name:pool-1-thread-1,执行:线程2

从执行的结果来看只执行了6个任务,其他的任务都被抛弃了。

DiscardOldestPolicy

DiscardOldestPolicy 当任务拒绝添加时,会抛弃任务队列中最先加入队列的任务,再把新任务添加进去。

示例说明

 ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                1,
                2,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(2),
                new ThreadPoolExecutor.CallerRunsPolicy());

执行结果:

添加第0个任务
添加第1个任务
添加第2个任务
添加第3个任务
添加第4个任务
添加第5个任务
invoke dealStock success
goodsId:手机
thread name:pool-1-thread-2,执行:线程3
thread name:pool-1-thread-1,执行:线程0
thread name:pool-1-thread-1,执行:线程2
thread name:pool-1-thread-2,执行:线程1

自定义拒绝策略

当线程池提供的拒绝策略无法满足要求时,我们可以采用自定义的拒绝策略,只需要实现RejectedExecutionHandler接口即可

public class CustRejectedExecutionHandler implements RejectedExecutionHandler
{
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
    {
        new Thread(r,"线程:"+new Random().nextInt(10)).start();
    }
}

  ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                1,
                2,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(2),
                new CustRejectedExecutionHandler());

执行结果:

thread name:客户线程:6,执行:线程5
thread name:pool-1-thread-1,执行:线程0
thread name:客户线程:8,执行:线程4
thread name:pool-1-thread-2,执行:线程3
thread name:pool-1-thread-1,执行:线程1
thread name:pool-1-thread-2,执行:线程2

从执行的结果来看,被拒绝的任务都在客户的新线程中执行。

小结

  • AbortPolicy:直接抛出异常,后续的任务不会执行
  • CallerRunsPolicy:子任务执行的时间过长,可能会阻塞主线程。
  • DiscardPolicy:不抛异常,任务直接丢弃
  • DiscardOldestPolicy;丢弃最先加入队列的任务

总结

本文对于线程的池的几种策略进行详细的讲解,在实际的生产中需要集合相关的场景来选择合适的拒绝策略,如有疑问,请随时反馈。

到此这篇关于Java ThreadPoolExecutor的拒绝策略的文章就介绍到这了,更多相关Java ThreadPoolExecutor拒绝策略内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详解Java ThreadPoolExecutor的拒绝策略

本文链接: https://lsjlt.com/news/166291.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详解Java ThreadPoolExecutor的拒绝策略
    目录背景线程池基本原理线程池拒绝策略AbortPolicyCallerRunsPolicyDiscardPolicy示例执行结果DiscardOldestPolicy示例说明自定义拒...
    99+
    2024-04-02
  • java线程池ThreadPoolExecutor的八种拒绝策略示例详解
    目录池化设计思想线程池触发拒绝策略的时机JDK内置4种线程池拒绝策略拒绝策略接口定义CallerRunsPolicy(调用者运行策略)AbortPolicy(中止策略)Discard...
    99+
    2024-04-02
  • Java线程池ThreadPoolExecutor拒绝策略有哪些
    本篇内容介绍了“Java线程池ThreadPoolExecutor拒绝策略有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!池化设计思想池...
    99+
    2023-06-16
  • java线程池ThreadPoolExecutor的拒绝策略有哪些
    本篇内容主要讲解“java线程池ThreadPoolExecutor的拒绝策略有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java线程池ThreadPoolExecutor的拒绝策略有哪...
    99+
    2023-06-21
  • Java线程池的四种拒绝策略详解
    目录预先配置配置线程池。创建线程任务拒绝策略一:AbortPolicy拒绝策略二:CallerRunsPolicy拒绝策略三:DiscardPolicy拒绝策略四:DiscardOl...
    99+
    2024-04-02
  • 详解什么是Java线程池的拒绝策略?
    目录一、拒绝策略1.1 AbortPolicy(默认拒绝策略)1.2 CallerRunsPolicy(使用调用线程池的线程来执行任务 )1.3 DiscardPolicy (忽略新...
    99+
    2024-04-02
  • Java线程池有哪些拒绝策略
    这期内容当中小编将会给大家带来有关Java线程池有哪些拒绝策略,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。池化设计思想池话设计应该不是一个新名词。我们常见的如java线程池、jdbc连接池、redis连...
    99+
    2023-06-16
  • Java线程池拒绝策略是什么
    本篇内容介绍了“Java线程池拒绝策略是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、CallerRunsPolicy(调用者运行策...
    99+
    2023-06-15
  • java 线程池如何执行策略又拒绝哪些策略
    目录线程池执行流程线程池拒绝策略DiscardPolicy拒绝策略AbortPolicy拒绝策略自定义拒绝策略总结前言: 聊到线程池就一定会聊到线程池的执行流程,也就是当有一个任务进...
    99+
    2024-04-02
  • java中线程池的拒绝策略有哪些
    本篇文章为大家展示了java中线程池的拒绝策略有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向对...
    99+
    2023-06-14
  • javaThreadPoolExecutor线程池拒绝策略避坑
    目录1.场景2. 原因分析3.总结4.思考1.场景 线程池使用DiscardOldestPolicy拒绝策略,阻塞队列使用ArrayBlockingQueue,发现在某些情形下对于得...
    99+
    2024-04-02
  • 详解Java策略模式
    一、策略模式到底是什么? 策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端...
    99+
    2024-04-02
  • Java之ThreadPoolExecutor类详解
    ThreadPoolExecutor ThreadPoolExecutor是线程池框架的一个核心类,线程池通过线程复用机制,并对线程进行统一管理 降低系统资源消耗。通过复用...
    99+
    2024-04-02
  • Java线程池 ThreadPoolExecutor 详解
    目录一 为什么要使用线程池二 线程池原理详解2.1 线程池核心组成2.2 Execute 原理三 线程池的使用3.1 创建线程池3.1.1 自定义线程池3.1.2 功能线程池3.1....
    99+
    2024-04-02
  • Java JVM编译策略案例详解
    解释器 当虚拟机启动时,解释器可以首先发挥作用,而不必等待编译器全部编译完成再执行,这样可以省去许多不必要的编译时间。并且随着程序运行时间的推移,编译器逐渐发挥作用,根据热点探测功能...
    99+
    2024-04-02
  • Java中ThreadPoolExecutor类的详细讲解
    这篇文章主要介绍“Java中ThreadPoolExecutor类的详细讲解”,在日常操作中,相信很多人在Java中ThreadPoolExecutor类的详细讲解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答...
    99+
    2023-06-20
  • java io流拒绝访问怎么解决
    当出现"java.io.IOException: Permission denied"的异常时,这表示你的代码无法访问指定的文件或目...
    99+
    2023-10-22
    java
  • java设计模式--策略模式详解
    目录策略模式Demo代码:总结策略模式 策略模式(Strategy Pattern)属于行为型模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。用算法族分别封装起来...
    99+
    2024-04-02
  • Java设计模式之java策略模式详解
    目录为什么使用策略模式?策略模式包含角色策略模式的类图排序案例策略模式的优点策略模式的缺点适用场景源码分析策略模式的典型应用Java Comparator 中的策略模式参考文...
    99+
    2024-04-02
  • 一文详解Java线程中的安全策略
    目录一、不可变对象二、线程封闭三、线程不安全类与写法四、线程安全-同步容器1. ArrayList -> Vector, Stack2. HashMap -> HashT...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作