java线程池拒绝策略_Java线程池拒绝策略

java线程池拒绝策略_Java线程池拒绝策略Java提供的策略实现CallerRunsPolicypublicstaticclassCallerRunsPolicyimplementsRejectedExecutionHandler{publicCallerRunsPolicy(){}publicvoidrejectedExecution(Runnabler,ThreadPoolExecutore){if(!…

大家好,又见面了,我是你们的朋友全栈君。

Java提供的策略实现

CallerRunsPolicy

public static class CallerRunsPolicy implements RejectedExecutionHandler {

public CallerRunsPolicy() { }

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

if (!e.isShutdown()) {

r.run();

}

}

}

CallerRunsPolicy顾名思义就是调用者自己执行,看实现就知道,如果线程池还没有关闭,就让将要被执行的线程自己调用自己的run方法,注意这里不是启动新的线程,只是执行run方法而已。

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());

}

}

AbortPolicy实现非常简单,直接抛出一个RejectedExecutionException异常,ThreadPoolExecutor默认的策略就是这一个。

DiscardPolicy

public static class DiscardPolicy implements RejectedExecutionHandler {

public DiscardPolicy() { }

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

}

}

DiscardPolicy策略就是什么也不做,就是把这一个任务(Runnable)丢弃,这是因为ThreadPoolExecutor在执行拒绝策略的时候就不会新建线程来执行Runnable,也不会加入任务队列了,所以在拒绝策略中什么都不做就是简单的丢弃掉了任务(Runnable)

DiscardOldestPolicy

public static class DiscardOldestPolicy implements RejectedExecutionHandler {

public DiscardOldestPolicy() { }

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

if (!e.isShutdown()) {

e.getQueue().poll();

e.execute(r);

}

}

}

DiscardOldestPolicy策略不是丢弃提交的任务中最老的,而是丢弃任务队列中队首的任务,然后再次提交新加入的任务。

拒绝策略与模式

从线程池的拒绝策略实现上也体现了面向对象的思想,把拒绝策略抽象在RejectedExecutionHandler接口中,ThreadPoolExecutor关联(更加具体的来说是聚合aggregation)RejectedExecutionHandler接口。

好歹我们也是学过设计模式的,在设计模式中这种模式叫做策略模式(Strategy),虽然实现类的后缀都是Policy但事实上这确实是一个策略模式的应用。对于不同拒绝算法的封装。可以看一下下面的类图。

4a12ec25787afe613c0bb864f65a18fd.png

JDK的源码中有大量的设计模式的使用,有的是非常直接的使用,甚至是为设计模式提供了接口,比如观察着模式。更多的是一些变形的使用,JDK对于设计模式的使用已经到了出神入化,大道无形的地步了。

自定义拒绝策略

既然设计上使用的是策略模式,那么对于我们来说扩展就是相当容易的事情了,简单来一个例子测试一下扩展线程池的策略模式。

import java.math.BigDecimal;

import java.util.concurrent.Executors;

import java.util.concurrent.LinkedBlockingQueue;

import java.util.concurrent.RejectedExecutionHandler;

import java.util.concurrent.ThreadPoolExecutor;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.atomic.AtomicInteger;

public class RejectPolicyTest {

private static AtomicInteger discardTaskNum = new AtomicInteger(0);

private static AtomicInteger executeTaskNum = new AtomicInteger(0);

public static void main(String[] args) {

int cpu = Runtime.getRuntime().availableProcessors();

ThreadPoolExecutor pool = new ThreadPoolExecutor(cpu, cpu, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(cpu),

Executors.defaultThreadFactory(), new RejectedExecutionHandler() {

@Override

public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

System.out.println(r + “:is discarded”);

discardTaskNum.incrementAndGet();

}

});

Task task = new Task();

for(int i = 0;i<100;i++){

pool.submit(task);

try {

TimeUnit.MILLISECONDS.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

pool.shutdown();

while(!pool.isTerminated());//等待所有的任务执行完成,包括任务队列中的任务

System.out.println(“discardNum:”+discardTaskNum.get());

System.out.println(“executeNum:”+executeTaskNum.get());

}

static class Task implements Runnable {

@Override

public void run() {

System.out.println(“task:” + Thread.currentThread().getName() + “is executing!”);

BigDecimal num1 = new BigDecimal(1.23456);

BigDecimal num2 = new BigDecimal(1.23456);

for (int i = 0; i < 5000000; i++) {//在我的机子上大概运行0.5s

num1.multiply(num2);

}

executeTaskNum.incrementAndGet();

}

}

}

在上面的实例中我们简单的实现了一个匿名的RejectedExecutionHandler,打印一下那些任务被丢弃了,顺便记录了一下被丢弃任务的数量。在上面的例子中的任务是执行5百万次BigDecimal类型的乘法。

总结

Java提供的4中默认策略分别是CallerRunsPolicy如果线程池没有关闭直接当前线程执行run方法,AbortPolicy抛出异常,DiscardPolicy丢弃任务,DiscardOldestPolicy丢弃任务队列头的任务。

Java线程池拒绝策略使用的是策略模式,抽象在RejectedExecutionHandler,如果需要扩展只需要实现RejectedExecutionHandler接口就可以了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/147710.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • linux下多线程通信(一)「建议收藏」

    linux下多线程通信(一)「建议收藏」在linux下进行多线程编程,肯定会涉及到线程通信问题,本文主要分析pipe,即管道在多线之间通信实现。#include&amp;amp;amp;amp;lt;unistd.h&amp;amp;amp;amp;gt;intpipe(intfiledes[2]);返回值:成功,返回0,否则返回-1。参数数组包含pipe使用的两个文件的描述符。fd[0]:读管道,fd[1]:写管道两个线程之间通信简单实现,单向pipe_1.c在这里插入代码片…

    2022年6月19日
  • 渗透测试工具Burp Suite详解[通俗易懂]

    渗透测试工具Burp Suite详解[通俗易懂]BurpSuite的安装BurpSuite是一款集成化的渗透测试工具,包含了很多功能,可以帮助我们高效地完成对Web应用程序的渗透测试和攻击。BurpSuite由Java语言编写,基于Java自身的跨平台性,使这款软件学习和使用起来更方便。BurpSuite不像其他自动化测试工具,它需要手工配置一些参数,触发一些自动化流程,然后才会开始工作。BurpSuite可执行程序是Java文件类型的jar文件,免费版可以从官网下载。免费版的BurpSuite会有许多限制,无法使用很多高

    2022年8月12日
  • mac navicat永久激活码最新_最新在线免费激活

    (mac navicat永久激活码最新)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlS32PGH0SQB-eyJsaWNlbnNlSWQi…

    2022年3月26日
  • java图书销售系统_基于Java Web的图书销售管理系统

    java图书销售系统_基于Java Web的图书销售管理系统项目描述本系统是基于jsp的网上图书销售,有比较符合初学者的简单而又不单一的界面,也有繁琐而又不过于抽象的后台数据处理。包含分类的登录用户(用户与管理员权限与界面不一),功能,登录与未登录有相应的权限设置,正常用户的图书检索与添加购物车、购买等操作。管理员可管理后台的各种信息。数据库中包含触发器用于图表的更新。作为平时与数据库、javaweb等相关的课程设计、大作业,特别适合初学者学习。奉上(包…

    2022年6月12日
  • vim编辑保存退出「建议收藏」

    vim编辑保存退出「建议收藏」vim编辑保存退出命令vim要打开的文件名字比如要打开test.log命令为:vimtest.log注意:如果不存在test.log则会自动创建进入编辑器后按字母“i”即可进入编辑状态(此时左下角会出现“插入”)退出的时候分为4种情况:保存退出、正常退出、不保存退出以及强制退出 2.1:保存退出:按“Esc”键后此时的“插入”会消失,然后按Shift+zz就可以保存修改内容并退出 2.2:不保存退出:当修改修改了一部分内容后发现修改错了,此时就会进

    2022年8月24日
  • 八种方式实现跨域请求

    八种方式实现跨域请求前端开发中我们经常会遇到跨域请求的情况,处理跨域请求方式很多,特整理如下:浏览器的同源策略​提到跨域不能不先说一下”同源策略”。​何为同源?只有当协议、端口、和域名都相同的页面,则两个页面具有相同的源。只要网站的协议名protocol、主机host、端口号port这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用,会受到同源策略的限制。​同源策略限制从

    2022年5月10日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号