大多数人不知道的:线程池CallerRunsPolicy()拒绝策略

多线程 专栏收录该内容
4 篇文章 0 订阅

在学习CallerRunsPolicy拒绝策略的时候,搜索了很多相关的知识,其他博主的描述是这样的:

第1种
在这里插入图片描述
第2种
在这里插入图片描述
第3种
在这里插入图片描述
第4种:JDK文档(汉化版)
在这里插入图片描述

他们的描述让我看的很懵逼,特别是第3种,仔细看他的测试代码,并没有用CallerRunsPolicy,而是用的AbortPolicy拒绝策略。。。。这是一篇高浏览量的博文,而且多人转载。


其中上面几种情况中写到的“execute方法的调用线程”、“调用者线程”、“execute函数的上层线程”、“execute本身的线程”就是指的主线程这里我的理解有误,可以先看完我的博文,再阅读评论区中 强哥叨逼叨和江小余两人的评论),举个例子如下图所示,主线程就是平时执行main方法中代码的线程
在这里插入图片描述

再通过一个例子详细说明:

class MyTask implements Runnable {
	private String id;

	public MyTask(String id) {
		this.id = id;
	}

	public void run() {
		System.out.println(id);
	}
}

public class RejectPolicy {
	public static void main(String[] args) {
		ExecutorService es = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS,
				new ArrayBlockingQueue<Runnable>(3), Executors.defaultThreadFactory(),
				new ThreadPoolExecutor.CallerRunsPolicy());
		MyTask t1 = new MyTask("id:1");
		MyTask t2 = new MyTask("id:2");
		MyTask t3 = new MyTask("id:3");
		MyTask t4 = new MyTask("id:4");
		MyTask t5 = new MyTask("id:5");
		MyTask t6 = new MyTask("id:6");
		MyTask t7 = new MyTask("id:7");

		es.execute(t1);
		es.execute(t2);
		es.execute(t3);
		es.execute(t4);
		es.execute(t5);
		es.execute(t6);
		es.execute(t7);
	}
}

这里使用主要参数是:核心线程数为2、最大线程数为2、有界队列(容量为3)、默认线程工厂、CallerRunsPolicy拒绝策略。

运行结果如下:

id:1
id:2
id:3
id:4
id:6
id:5
id:7

可以看到所有的任务都执行了,没有真正意义上被拒绝的

代码中定义了核心线程数为2的线程池,一共有7个任务要执行,其中2个任务创建线程执行去了,3个任务放入了任务队列(workQueue)。

当提交到第6个任务的时候,会触发拒绝策略,在这里我们配置了CallerRunsPolicy策略,主线程直接执行第六个任务去了,不再向下执行main方法中的es.execute(t7)这段代码。也就是说,在本程序中最多会有3个任务在执行,3个在等待。由此限制了线程池的等待任务数与执行线程数。所以JDK文档才会说:“这提供了一个简单的反馈控制机制,将降低新任务提交的速度”。

在这里插入图片描述

我的一点个人理解,希望能有助理解。

PS:特别感谢评论区中强哥叨逼叨和江小余两人的评论,将其理解为“主线程”是我一开始的想法,现在再回头看叫“调用者线程”才是最准确的。

  • 12
    点赞
  • 7
    评论
  • 18
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值