您现在的位置是:亿华云 > 知识
通过线程池方式改造Stream.parallel()并行流
亿华云2025-10-09 13:35:01【知识】0人已围观
简介来源:哪吒编程上一篇简单聊一聊公平锁和非公平锁,parallel并行流,提到了一个IntStream.rangeClosed并行流问题,很多小伙伴,对这个比较陌生,想用线程池的方式改造一下。一、Int
来源:哪吒编程
上一篇简单聊一聊公平锁和非公平锁,通过parallel并行流,线程行流提到了一个IntStream.rangeClosed并行流问题,池方很多小伙伴,式改对这个比较陌生,通过想用线程池的线程行流方式改造一下。
一、池方IntStream.rangeClosed并行流
@Datapublic class LockTest1{
public static void main(String[] args){
IntStream.rangeClosed(1,式改 100000).parallel().forEach(i -> newLockTest1().increase());
System.out.println(time);
}
private static int time = 0;
private static Object lock = newObject();
public void increase(){
synchronized(lock) {
time++;
}
}
}
二、线程池方式改造
不会那些新特性,通过还是线程行流原始的香啊,写起代码,池方得心应手。式改
1、通过创建线程池
这时候,线程行流有些小伙伴,池方又陷入了选择恐惧症。用哪个线程池比较好呢?
简单回顾一下:
单线程池newSingleThreadExecutor(),只有一个核心线程的线程池,保证任务按FIFO顺序一个个执行;固定线程数线程池newFixedThreadPool(10),固定数量的可复用的线程数,来执行任务。当线程数达到最大核心线程数,则加入队列等待有空闲线程时再执行;可缓存线程池newCachedThreadPool(),创建的都是非核心线程,而且最大线程数为Interge的最大值,网站模板空闲线程存活时间是1分钟。如果有大量耗时的任务,则不适该创建方式,它只适用于生命周期短的任务;固定线程数newScheduledThreadPool(10),支持定时和周期性任务newScheduledThreadPool(10),顾名思义,在固定线程数的前提下,添加了定时任务。最常用的还是固定线程数线程池newFixedThreadPool(10)。
@Datapublic class LockTest2{
public static void main(String[] args){
ExecutorService executorService = Executors.newFixedThreadPool(200);
for (int i = 0; i < 100000; i++) {
Thread0926 thread = newThread0926();
executorService.execute(thread);
}
System.out.println(time);
}
private static int time = 0;
private static Object lock = newObject();
public void increase(){
synchronized(lock) {
time++;
}
}
}
2、线程类
public class Thread0926 implements Runnable{
@Override public void run(){
LockTest2 lockTest = newLockTest2();
lockTest.increase();
}
}
3、信心满满,走起来
我草,这不对啊,不应该是100000嘛?又把老子整不会了~

三、再次解决并发时i++原子性问题
上一篇测试过,使用synchronized代码块是可以解决i++线程安全问题的,这次怎么不好使了?
上面的代码中,synchronized (lock)锁住了time++,lock是静态变量,所以属于类级别的锁。站群服务器但是新建的线程是一个新的类,超出了锁的范围,所以失效。
那么,在当前类中,开启线程,是不是就可以了呢?试一下
public class LockTest4{
private static int time = 0;
private static Object lock = newObject();
public static void main(String[] args) throws InterruptedException{
for (int i = 0; i < 200; i++) {
Thread thread = newThread(() -> {
for (int j = 0; j < 500; j++) {
synchronized(lock) {
time++;
}
}
});
thread.start();
}
Thread.sleep(3000);
System.out.println(time);
}
}
当然,在synchronized代码块中,使用synchronized (LockTest4.class)也是可以的,效果是一样的。

四、并行流与多线程
并行流的本质的是并行,多线程的本质是并发。
并行指当多核CPU中的一个CPU执行一个线程时,其它CPU能够同时执行另一个线程,两个线程之间不会抢占CPU资源,服务器托管可以同时运行。
并发指在一段时间内CPU处理多个线程,这些线程会抢占CPU资源,CPU资源根据时间片周期在多个线程之间来回切换,多个线程在一段时间内同时运行,而在同一时刻不是同时运行的。
1、并行和并发的区别?
并行指多个线程在一段时间的每个时刻都同时运行,并发指多个线程在一段时间内同时运行(不是同一时刻,一段时间内交叉执行)并行的多个线程不会抢占系统资源,并发的多个线程会抢占系统资源;并行是多CPU的产物,单核CPU中只有并发,没有并行;
2、并行和并发的使用场景
(1)IO密集场景
场景应用程序开发,提供http接口、数据库查询、微服务调用都是IO请求,IO请求时几乎不消耗cpu,这是为了提供cup使用率,建议使用多线程并发,线程数可以远大于cpu核数。
(2)cup密集场景
对应大量的加减乘除运算、md5、hash等运算操作,需要持续使用cpu,需要让多核cpu并行运算,适合使用forkjoin并行计算。
技术场景多线程不足,使用多线程技术,也能提高性能,但是线程设置过大会浪费cpu线程切换的时间,如果线程任务分配不均匀,会导致有的cpu忙碌有的cpu空闲。
很赞哦!(44)
相关文章
- 最后提醒我们,域名到期后要及时更新域名,否则可能会丢掉域名,每次抢先注册都不会成功。
- 为什么用Dubbo而不是Spring Cloud?基于支付场景的微服务高可用架构实战
- JavaScript 如何打败众语言,成为 Node 的实现语言?
- 如何从零开始构建深度学习项目?这里有一份详细的教程
- 3、不明先知,根据相关征兆预测可能发生的事件,以便提前做好准备,赶紧注册相关域名。;不差钱域名;buchaqian抢先注册,就是这种敏感类型。预言是最敏感的状态。其次,你应该有眼力。所谓眼力,就是善于从社会上时不时出现的各种热点事件中获取与事件相关的域名资源。眼力的前提是对域名领域的熟悉和丰富的知识。
- 时薪10K的高级程序猿教你如何用Python一步步来搭建一个区块链
- 一份靠谱的数据开发从业指南
- 图解广告及推荐系统架构流程
- 为什么大家都选优质域名?到底存在着什么好处?
- 小200行Python代码做了一个换脸程序
站长推荐
其次,一般域名注册有一个获取密码的按钮,域名注册商点击后会向您发送密码。在得到域名注册商发送的密码后,将其传输到域名服务提供商网站,然后输入密码,此时域名呈现申请状态。提交申请后,原注册人通常会向您发送一封电子邮件,询问您是否同意转让。此时,您只需点击同意转移按钮,域名注册商就可以成功转移。
PHP FFI 允许在 PHP 脚本中嵌入 C 代码
用10行Python代码进行图像识别
编程语言1月排行榜:C是年度语言,Python增长量第二
3、商标域名一经注册,就可以作为域名裁决过程中的主要信息之一。这可以大大增加公司被抢注的相关域名胜诉的机会。
软件正在蚕食世界,而开发者的价值观成了较大的 Bug
在本地开发中使用Kubernetes
华为年终分红曝光!应届生最高20万,老员工最高300万