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不使用预期的线程数相关推荐

  1. Java线程池如何合理配置核心线程数

    我相信大家都用过线程池,但是线程池数量设置为多少比较合理呢? 线程数的设置的最主要的目的是为了充分并合理地使用 CPU 和内存等资源,从而最大限度地提高程序的性能,因此让我们一起去探索吧! 首先要考虑 ...

  2. java 最大线程数 设定_Java8 parallelStream 修改默认的线程数量

    parallelStream默认使用了fork-join框架,其默认线程数是CPU核心数. 通过查阅资料,发现有两种方法来修改默认的多线程数量: 1.全局设置 在运行代码之前,加入如下代码: Syst ...

  3. weblogic下开发web项目时修改java文件不用重启的绿色方法,不用修改weblogic的配置文件、不用jar...

    2019独角兽企业重金招聘Python工程师标准>>> weblogic下开发web项目时修改java文件不用重启的绿色方法,不用修改weblogic的配置文件.不用jar      ...

  4. java语言不用担心内存吗_不用担心智能手机的电池,只需使用它

    java语言不用担心内存吗 When you're trying to get the most life out of your device, it's easy to overthink bat ...

  5. java控制台输出图书馆管理系统(只用java代码不用数据库和GUI等)

    java控制台输出图书馆管理系统(只用java代码不用数据库和GUI,java入门的新手秒懂) 在个项目中,我只用数组保存数据,和只用for循环和if条件语句来完成,连数组工具类都没用,所以导致要用到 ...

  6. Java:不用就卸载吧!

    Java:不用就卸载吧! 投递人 itwriter 发布于 2010-10-20 11:33 评论(11) 有3506人阅读  原文链接  [收藏] 编者按:在<2010年10月编程语言排行榜& ...

  7. 一文详解java线程池 详解Java线程池的七个参数 详解池化技术 java如何选择核心线程数 详解Java线程池的拒绝策略

    目录 引言 线程池使用场景 加快请求响应(响应时间优先) 加快处理大任务(吞吐量优先) 特殊说明 线程池的池化技术 线程池的创建 手动创建 创建newFixedThreadPool线程池 创建newS ...

  8. 【Java 并发编程】线程池机制 ( ThreadPoolExecutor 线程池构造参数分析 | 核心线程数 | 最大线程数 | 非核心线程存活时间 | 任务阻塞队列 )

    文章目录 前言 一.ThreadPoolExecutor 构造参数 二.newCachedThreadPool 参数分析 三.newFixedThreadPool 参数分析 四.newSingleTh ...

  9. java压测请求线程数_程序员撕开京东 618 大促压测的另一面 | 原力计划

    作者 | 天涯泪小武 责编 | 王晓曼 出品 | CSDN博客 前天618大促演练进行了全链路压测,在此之前刚好我的热key探测框架也已经上线灰度一周了,小范围上线了几千台服务器,每秒大概接收几千个k ...

最新文章

  1. 慢连接 java_记一次redis的java客户端lettuce操作慢的解决方案
  2. net-speeder 安装
  3. 单身萌妹纸手把手教你用产品思维追女生
  4. Codeforces Round #491 (Div.2)
  5. 数组作为方法返回值_返回地址
  6. centos rpm安装mysql5.5_CentOS下以RPM方式安装MySQL5.5
  7. c++ fmt 库安装和使用示例、clion配置
  8. 期待三分天下开源芯片有其一
  9. 一文搞懂IT基础知识,讲通HTTP、TCP、IP、以太网
  10. 微信sdk 隐藏右上角菜单项
  11. server2005系统表知多少 之sysdatabases
  12. 气体管道管径及流量对照表_气体涡轮流量计的选型要点?
  13. centos系统安装pycharm编辑器
  14. 如何高度自适应_精准放疗:TOMO如何做到自适应放疗?
  15. Android Binder -- AIDL 原理
  16. 《最好的告别》是有尊严的离开
  17. phpMyAdmin 常见漏洞利用记录
  18. arduino(4):使用ESP8266,了解下相关芯片生产厂商,安信可的开发板子。
  19. 操作系统常用缩写总结
  20. wps多人协作后怎么保存_wps在线协作,多人实时填表,数据统计方法

热门文章

  1. c语言汽水瓶换汽水的编程题,c语言:2种方法编程及优化;喝汽水问题
  2. java占位符打印_java简单日志打印规范小记
  3. redmine备份_Redmine 数据迁移记录
  4. 444 nginx_nginx 安全问题
  5. html中index.css里面写什么,css中z-index是什么意思?
  6. php 提交表单跳转页面,form表单页面跳转方式提交练习
  7. Python实现字符串反转的几种方法
  8. Python 常见语法逻辑错误收集
  9. 购买过php,【已解决】PHP项目需求:用户购买商品时,给上级发送一条通知(无限级下级会员)...
  10. 贴片铝电容识别及型号_贴片钽电容封装及规格和参数资料