文档章节

限制Java线程池运行线程以及等待线程数量的策略

zjg23
 zjg23
发布于 2016/10/09 14:06
字数 514
阅读 82
收藏 0

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

对于java.util.concurrent.Executors所提供的FixedThreadPool,可以保证可以在内存中有固定数量的线程数运行。但是由于FixedThreadPool绑定的是LinkedBlockingQueue。队列的上限没有限制(默认上限为Integer.MAX_VALUE),不断的提交新的线程,会造成任务在内存中长时间的堆积。

我们有可能面临如下的场景,主线程不断地提交任务线程,希望有固定数量的在线程中运行,也不想造成线程在内存中大量的等待堆积。由此需要我们自己定义一个线程池策略。ThreadPoolExecutor为我们线程池的设置提供了很大的灵活性。

首先看FixedThreadPool的实现:

public static ExecutorService More ...newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>(),
                                          threadFactory);
        }

可以看到,FixedThreadPool绑定的是LinkedBlockingQueue<Runnable>。我们需要做的第一个改造就是绑定有大小上线的BlockingQueue,在我的实现中绑定ArrayBlockingQueue<Runnable>并设置了size。

第二个是采用CallerRunsPolicy。ThreadPoolExecutor可以定义不同的任务拒绝策略。CallerRunsPolicy指的是当线程池拒绝该任务的时候,线程在本地线程直接execute。这样就限制了本地线程的循环提交流程。

 

BlockingQueue<Runnable> workingQueue = new ArrayBlockingQueue<Runnable>(10);
    RejectedExecutionHandler rejectedExecutionHandler =
        new ThreadPoolExecutor.CallerRunsPolicy();
    ExecutorService threadPool = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS,
        workingQueue, rejectedExecutionHandler);

    for (int i = 0; i < 100; i++) {
      
      threadPool.submit(new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
          System.out.println("thread " + String.valueOf(threadNo) + " is called");
          Thread.sleep(10000);
          System.out.println("thread " + String.valueOf(threadNo) + " is awake");
          throw new Exception();
        }

 

 

代码中定义了大小为10的线程池,for循环提交了100个线程的时候,10个执行线程,10个线程放入了workingQueue。当提交到第21个线程的时候,会触发RejectedExecutionHandler。在这里我们配置了CallerRunsPolicy策略。所以会在主线程直接执行该线程。也就是说,在本程序中最多会有11个线程在执行,10个线程在等待。由此限制了线程池的等待线程数与执行线程数。

本文转载自:https://segmentfault.com/a/1190000005876711

zjg23

zjg23

粉丝 22
博文 127
码字总数 45941
作品 0
济南
程序员
私信 提问
加载中

评论(0)

java并发编程实战:第八章----线程池的使用

一、在任务和执行策略之间隐性耦合 Executor框架将任务的提交和它的执行策略解耦开来。虽然Executor框架为制定和修改执行策略提供了相当大的灵活性,但并非所有的任务都能适用所有的执行策略...

osc_dfi5j6xi
2018/05/11
2
0
Java并发编程系列-(6) Java线程池

目前已经更新完《Java并发编程》,《Docker教程》和《JVM性能优化》,欢迎关注【后端精进之路】,轻松阅读全部文章。 <div align=center><img src="http://ww1.sinaimg.cn/large/a18449c6gy1g...

osc_1njk964l
04/16
12
0
Java并发——线程池Executor框架

线程池 无限制的创建线程 若采用"为每个任务分配一个线程"的方式会存在一些缺陷,尤其是当需要创建大量线程时: 线程生命周期的开销非常高 资源消耗 稳定性 引入线程池 任务是一组逻辑工作单...

osc_p3rdih8s
2019/10/08
2
0
「建议心心」要就来15道多线程面试题一次爽到底(1.1w字用心整理)

、 本文是给「建议收藏」200MB大厂面试文档,整理总结2020年最强面试题库「CoreJava篇」写的答案,所有相关文章已经收录在码云仓库:https://gitee.com/bingqilinpeishenme/Java-interview 千...

osc_o60il3e6
04/16
2
0
使用异步任务降低API延迟_实践总结

之前在想如何降低API的延迟,这些API里有几个比较耗时的操作且是串行执行,那通过异步执行的方式理论上可以降低运行的时间,如下图所示: 具体的实现比较简单,例如这样: 用java8引入的即可...

osc_p8zyme9p
2018/02/13
2
0

没有更多内容

加载失败,请刷新页面

加载更多

Docker入门:什么是 Docker ?

Docker 解决了软件环境部署复杂的问题。 对于一个传统的软件工程,开发人员把写好的代码放到服务器上去运行是一件很头疼的事情,因为常常会出现环境不兼容而导致各种各样的 Bug。 比如说,开...

开源仔
11分钟前
13
1
idea激活教程,最新!!!

1.下载破解补丁(关键)。 破解补丁:JetbrainsIdesCrack-4.2-release.jar 百度云地址:https://pan.baidu.com/s/18ovphd7sm7oYXQb4CInaUg 提取码:cw2j 2.寻找到idea的安装目录,将下载下来...

osc_lgbm94am
11分钟前
18
0
共同创业五年,技术总监却突然就这么离职了

一、 引子 有一天,跟一位原同事老A聊起职场的一些情况,期间无意中提到了原公司的技术总监。我说这位技术总监带领公司从一家十几人的小团队,做到四百人的公司,作为同样都是开发者,而且以...

osc_5k0epejp
12分钟前
11
0
Python 中国象棋源码 V1

Pygame 做的中国象棋,一直以来喜欢下象棋,写了 python 就拿来做一个试试,水平有限,电脑走法水平低,需要在下次版本中更新电脑走法,希望源码能帮助大家更好的学习 python。总共分为四个文...

osc_wbienwab
14分钟前
13
0
flac是什么格式?flac无法正常播放怎么办?

相比以前的磁带和光碟,现如今听音乐可就简单方便多了,直接从音乐网站上下载歌曲就可以了。当然,不同的网站,下载下来的音乐格式可能是不一样的。除了咱们比较熟悉的MP3之外,网上下载下来...

深蓝月上
14分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部