java用不用stream_Java parallelStream不使用预期的线程数
Java 8 parallelStream似乎使用的线程数多于系统属性java.util.concurrent.ForkJoinPool.common.parallelism指定的线程数.这些单元测试显示我使用自己的ForkJoinPool使用所需数量的线程处理任务,但是当使用parallelStream时,线程数高于预期.
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.Assert.assertTrue;
public class ParallelStreamTest {
private static final int TOTAL_TASKS = 1000;
@Test
public void testParallelStreamWithParallelism1() throws InterruptedException {
final Integer maxThreads = 1;
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", maxThreads.toString());
List objects = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
objects.add(i);
}
final AtomicInteger concurrentThreads = new AtomicInteger(0);
final AtomicInteger taskCount = new AtomicInteger(0);
objects.parallelStream().forEach(i -> {
processTask(concurrentThreads, maxThreads); //expected to be called one at the time
taskCount.addAndGet(1);
});
assertTrue(taskCount.get() == TOTAL_TASKS);
}
@Test
public void testMyOwnForkJoinPoolWithParallelism1() throws InterruptedException {
final Integer threads = 1;
List objects = new ArrayList<>();
for (int i = 0; i < TOTAL_TASKS; i++) {
objects.add(i);
}
ForkJoinPool forkJoinPool = new ForkJoinPool(1);
final AtomicInteger concurrentThreads = new AtomicInteger(0);
final AtomicInteger taskCount = new AtomicInteger(0);
forkJoinPool.submit(() -> objects.parallelStream().forEach(i -> {
processTask(concurrentThreads, threads); //expected to be called one at the time
taskCount.addAndGet(1);
}));
forkJoinPool.shutdown();
forkJoinPool.awaitTermination(1, TimeUnit.MINUTES);
assertTrue(taskCount.get() == TOTAL_TASKS);
}
/**
* It simply processes a task increasing first the concurrentThreads count
*
* @param concurrentThreads Counter for threads processing tasks
* @param maxThreads Maximum number of threads that are expected to be used for processing tasks
*/
private void processTask(AtomicInteger concurrentThreads, int maxThreads) {
int currentConcurrentThreads = concurrentThreads.addAndGet(1);
if (currentConcurrentThreads > maxThreads) {
throw new IllegalStateException("There should be no more than " + maxThreads + " concurrent thread(s) but found " + currentConcurrentThreads);
}
// actual processing would go here
concurrentThreads.decrementAndGet();
}
}
应该只有一个线程用于处理任务,因为ForkJoinPool具有parallelism = 1和java.util.concurrent.ForkJoinPool.common.parallelism = 1.因此,两个测试都应该通过,但testParallelStreamWithParallelism1失败:
java.lang.IllegalStateException: There should be no more than 1 concurrent thread(s) but found 2
似乎设置java.util.concurrent.ForkJoinPool.common.parallelism = 1没有按预期工作,并且同时处理了多个并发任务.
有任何想法吗?
解决方法:
Fork / Join池的并行性设置确定了池工作线程的数量,但是从调用者线程开始,例如,主线程也将在作业上工作,使用公共池时总会有一个线程.这就是default setting of the common pool is “number of cores minus one”让实际工作线程数等于核心数的原因.
使用自定义Fork / Join池,流操作的调用者线程已经是池的工作线程,因此,利用它来处理作业不会增加实际工作线程数.
必须强调的是,Stream实现和Fork / Join池之间的交互完全没有指定,因为流使用Fork / Join框架的事实是一个实现细节.无法保证更改默认池的属性对流有任何影响,也不保证在自定义Fork / Join池的任务中调用流操作将使用该自定义池.
标签:java,java-8,java-stream,multithreading
来源: https://codeday.me/bug/20190828/1753500.html
java用不用stream_Java parallelStream不使用预期的线程数相关推荐
- Java线程池如何合理配置核心线程数
我相信大家都用过线程池,但是线程池数量设置为多少比较合理呢? 线程数的设置的最主要的目的是为了充分并合理地使用 CPU 和内存等资源,从而最大限度地提高程序的性能,因此让我们一起去探索吧! 首先要考虑 ...
- java 最大线程数 设定_Java8 parallelStream 修改默认的线程数量
parallelStream默认使用了fork-join框架,其默认线程数是CPU核心数. 通过查阅资料,发现有两种方法来修改默认的多线程数量: 1.全局设置 在运行代码之前,加入如下代码: Syst ...
- weblogic下开发web项目时修改java文件不用重启的绿色方法,不用修改weblogic的配置文件、不用jar...
2019独角兽企业重金招聘Python工程师标准>>> weblogic下开发web项目时修改java文件不用重启的绿色方法,不用修改weblogic的配置文件.不用jar ...
- java语言不用担心内存吗_不用担心智能手机的电池,只需使用它
java语言不用担心内存吗 When you're trying to get the most life out of your device, it's easy to overthink bat ...
- java控制台输出图书馆管理系统(只用java代码不用数据库和GUI等)
java控制台输出图书馆管理系统(只用java代码不用数据库和GUI,java入门的新手秒懂) 在个项目中,我只用数组保存数据,和只用for循环和if条件语句来完成,连数组工具类都没用,所以导致要用到 ...
- Java:不用就卸载吧!
Java:不用就卸载吧! 投递人 itwriter 发布于 2010-10-20 11:33 评论(11) 有3506人阅读 原文链接 [收藏] 编者按:在<2010年10月编程语言排行榜& ...
- 一文详解java线程池 详解Java线程池的七个参数 详解池化技术 java如何选择核心线程数 详解Java线程池的拒绝策略
目录 引言 线程池使用场景 加快请求响应(响应时间优先) 加快处理大任务(吞吐量优先) 特殊说明 线程池的池化技术 线程池的创建 手动创建 创建newFixedThreadPool线程池 创建newS ...
- 【Java 并发编程】线程池机制 ( ThreadPoolExecutor 线程池构造参数分析 | 核心线程数 | 最大线程数 | 非核心线程存活时间 | 任务阻塞队列 )
文章目录 前言 一.ThreadPoolExecutor 构造参数 二.newCachedThreadPool 参数分析 三.newFixedThreadPool 参数分析 四.newSingleTh ...
- java压测请求线程数_程序员撕开京东 618 大促压测的另一面 | 原力计划
作者 | 天涯泪小武 责编 | 王晓曼 出品 | CSDN博客 前天618大促演练进行了全链路压测,在此之前刚好我的热key探测框架也已经上线灰度一周了,小范围上线了几千台服务器,每秒大概接收几千个k ...
最新文章
- 慢连接 java_记一次redis的java客户端lettuce操作慢的解决方案
- net-speeder 安装
- 单身萌妹纸手把手教你用产品思维追女生
- Codeforces Round #491 (Div.2)
- 数组作为方法返回值_返回地址
- centos rpm安装mysql5.5_CentOS下以RPM方式安装MySQL5.5
- c++ fmt 库安装和使用示例、clion配置
- 期待三分天下开源芯片有其一
- 一文搞懂IT基础知识,讲通HTTP、TCP、IP、以太网
- 微信sdk 隐藏右上角菜单项
- server2005系统表知多少 之sysdatabases
- 气体管道管径及流量对照表_气体涡轮流量计的选型要点?
- centos系统安装pycharm编辑器
- 如何高度自适应_精准放疗:TOMO如何做到自适应放疗?
- Android Binder -- AIDL 原理
- 《最好的告别》是有尊严的离开
- phpMyAdmin 常见漏洞利用记录
- arduino(4):使用ESP8266,了解下相关芯片生产厂商,安信可的开发板子。
- 操作系统常用缩写总结
- wps多人协作后怎么保存_wps在线协作,多人实时填表,数据统计方法
热门文章
- c语言汽水瓶换汽水的编程题,c语言:2种方法编程及优化;喝汽水问题
- java占位符打印_java简单日志打印规范小记
- redmine备份_Redmine 数据迁移记录
- 444 nginx_nginx 安全问题
- html中index.css里面写什么,css中z-index是什么意思?
- php 提交表单跳转页面,form表单页面跳转方式提交练习
- Python实现字符串反转的几种方法
- Python 常见语法逻辑错误收集
- 购买过php,【已解决】PHP项目需求:用户购买商品时,给上级发送一条通知(无限级下级会员)...
- 贴片铝电容识别及型号_贴片钽电容封装及规格和参数资料