当前位置:首页 > 科技  > 软件

通过线程池方式改造Stream.parallel()并行流

来源: 责编: 时间:2023-10-13 14:36:41 198观看
导读大家好,我是哪吒。上一篇简单聊一聊公平锁和非公平锁,parallel并行流,提到了一个IntStream.rangeClosed并行流问题,很多小伙伴,对这个比较陌生,想用线程池的方式改造一下。一、IntStream.rangeClosed并行流@Datapublic clas

oYr28资讯网——每日最新资讯28at.com

大家好,我是哪吒。

上一篇简单聊一聊公平锁和非公平锁,parallel并行流,提到了一个IntStream.rangeClosed并行流问题,很多小伙伴,对这个比较陌生,想用线程池的方式改造一下。oYr28资讯网——每日最新资讯28at.com

一、IntStream.rangeClosed并行流

@Datapublic class LockTest1 {    public static void main(String[] args) {        IntStream.rangeClosed(1, 100000).parallel().forEach(i -> new LockTest1().increase());        System.out.println(time);    }    private static int time = 0;    private static Object lock = new Object();    public void increase() {        synchronized (lock) {            time++;        }    }}

二、线程池方式改造

不会那些新特性,还是原始的香啊,写起代码,得心应手。oYr28资讯网——每日最新资讯28at.com

1、创建线程池

这时候,有些小伙伴,又陷入了选择恐惧症。用哪个线程池比较好呢?oYr28资讯网——每日最新资讯28at.com

简单回顾一下:oYr28资讯网——每日最新资讯28at.com

  • 单线程池newSingleThreadExecutor(),只有一个核心线程的线程池,保证任务按FIFO顺序一个个执行;
  • 固定线程数线程池newFixedThreadPool(10),固定数量的可复用的线程数,来执行任务。当线程数达到最大核心线程数,则加入队列等待有空闲线程时再执行;
  • 可缓存线程池newCachedThreadPool(),创建的都是非核心线程,而且最大线程数为Interge的最大值,空闲线程存活时间是1分钟。如果有大量耗时的任务,则不适该创建方式,它只适用于生命周期短的任务;
  • 固定线程数newScheduledThreadPool(10),支持定时和周期性任务newScheduledThreadPool(10),顾名思义,在固定线程数的前提下,添加了定时任务。

最常用的还是固定线程数线程池newFixedThreadPool(10)。oYr28资讯网——每日最新资讯28at.com

@Datapublic class LockTest2 {    public static void main(String[] args) {        ExecutorService executorService = Executors.newFixedThreadPool(200);        for (int i = 0; i < 100000; i++) {            Thread0926 thread = new Thread0926();            executorService.execute(thread);        }        System.out.println(time);    }    private static int time = 0;    private static Object lock = new Object();    public void increase() {        synchronized (lock) {            time++;        }    }}

2、线程类

public class Thread0926 implements Runnable{    @Override    public void run() {        LockTest2 lockTest = new LockTest2();        lockTest.increase();    }}

3、信心满满,走起来

我草,这不对啊,不应该是100000嘛?又把老子整不会了~oYr28资讯网——每日最新资讯28at.com

oYr28资讯网——每日最新资讯28at.com

三、再次解决并发时i++原子性问题

上一篇测试过,使用synchronized代码块是可以解决i++线程安全问题的,这次怎么不好使了?oYr28资讯网——每日最新资讯28at.com

上面的代码中,synchronized (lock)锁住了time++,lock是静态变量,所以属于类级别的锁。但是新建的线程是一个新的类,超出了锁的范围,所以失效。oYr28资讯网——每日最新资讯28at.com

那么,在当前类中,开启线程,是不是就可以了呢?试一下oYr28资讯网——每日最新资讯28at.com

public class LockTest4 {    private static int time = 0;    private static Object lock = new Object();    public static void main(String[] args) throws InterruptedException {        for (int i = 0; i < 200; i++) {            Thread thread = new Thread(() -> {                for (int j = 0; j < 500; j++) {                    synchronized (lock) {                        time++;                    }                }            });            thread.start();        }        Thread.sleep(3000);        System.out.println(time);    }}

当然,在synchronized代码块中,使用synchronized (LockTest4.class)也是可以的,效果是一样的。oYr28资讯网——每日最新资讯28at.com

oYr28资讯网——每日最新资讯28at.com

四、并行流与多线程

并行流的本质的是并行,多线程的本质是并发。oYr28资讯网——每日最新资讯28at.com

并行指当多核CPU中的一个CPU执行一个线程时,其它CPU能够同时执行另一个线程,两个线程之间不会抢占CPU资源,可以同时运行。oYr28资讯网——每日最新资讯28at.com

并发指在一段时间内CPU处理多个线程,这些线程会抢占CPU资源,CPU资源根据时间片周期在多个线程之间来回切换,多个线程在一段时间内同时运行,而在同一时刻不是同时运行的。oYr28资讯网——每日最新资讯28at.com

1、并行和并发的区别?

  • 并行指多个线程在一段时间的每个时刻都同时运行,并发指多个线程在一段时间内同时运行(不是同一时刻,一段时间内交叉执行)。
  • 并行的多个线程不会抢占系统资源,并发的多个线程会抢占系统资源。
  • 并行是多CPU的产物,单核CPU中只有并发,没有并行。

oYr28资讯网——每日最新资讯28at.com

2、并行和并发的使用场景

(1)IO密集场景

场景应用程序开发,提供http接口、数据库查询、微服务调用都是IO请求,IO请求时几乎不消耗cpu,这是为了提供cup使用率,建议使用多线程并发,线程数可以远大于cpu核数。oYr28资讯网——每日最新资讯28at.com

(2)cup密集场景

对应大量的加减乘除运算、md5、hash等运算操作,需要持续使用cpu,需要让多核cpu并行运算,适合使用forkjoin并行计算oYr28资讯网——每日最新资讯28at.com

技术场景多线程不足,使用多线程技术,也能提高性能,但是线程设置过大会浪费cpu线程切换的时间,如果线程任务分配不均匀,会导致有的cpu忙碌有的cpu空闲。oYr28资讯网——每日最新资讯28at.com

oYr28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-13282-0.html通过线程池方式改造Stream.parallel()并行流

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: C# Dev Kit for Visual Studio Code 用法详解

下一篇: Java中equals和==的区别

标签:
  • 热门焦点
  • 小米平板5 Pro 12.4简评:多专多能 兼顾影音娱乐的大屏利器

    小米平板5 Pro 12.4简评:多专多能 兼顾影音娱乐的大屏利器

    疫情带来了网课,网课盘活了安卓平板,安卓平板市场虽然中途停滞了几年,但好的一点就是停滞的这几年行业又有了新的发展方向,例如超窄边框、高刷新率、多摄镜头组合等,这就让安卓
  • 7月安卓手机性能榜:红魔8S Pro再夺榜首

    7月安卓手机性能榜:红魔8S Pro再夺榜首

    7月份的手机市场风平浪静,除了红魔和努比亚带来了两款搭载骁龙8Gen2领先版处理器的新机之外,别的也想不到有什么新品了,这也正常,通常6月7月都是手机厂商修整的时间,进入8月份之
  • 线程通讯的三种方法!通俗易懂

    线程通讯的三种方法!通俗易懂

    线程通信是指多个线程之间通过某种机制进行协调和交互,例如,线程等待和通知机制就是线程通讯的主要手段之一。 在 Java 中,线程等待和通知的实现手段有以下几种方式:Object 类下
  • Rust中的高吞吐量流处理

    Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • Automa-通过连接块来自动化你的浏览器

    Automa-通过连接块来自动化你的浏览器

    1、前言通过浏览器插件可实现自动化脚本的录制与编写,具有代表性的工具就是:Selenium IDE、Katalon Recorder,对于简单的业务来说可快速实现自动化的上手工作。Selenium IDEKat
  • 一篇聊聊Go错误封装机制

    一篇聊聊Go错误封装机制

    %w 是用于错误包装(Error Wrapping)的格式化动词。它是用于 fmt.Errorf 和 fmt.Sprintf 函数中的一个特殊格式化动词,用于将一个错误(或其他可打印的值)包装在一个新的错误中。使
  • 谷歌KDD'23工作:如何提升推荐系统Ranking模型训练稳定性

    谷歌KDD'23工作:如何提升推荐系统Ranking模型训练稳定性

    谷歌在KDD 2023发表了一篇工作,探索了推荐系统ranking模型的训练稳定性问题,分析了造成训练稳定性存在问题的潜在原因,以及现有的一些提升模型稳定性方法的不足,并提出了一种新
  • 使用LLM插件从命令行访问Llama 2

    使用LLM插件从命令行访问Llama 2

    最近的一个大新闻是Meta AI推出了新的开源授权的大型语言模型Llama 2。这是一项非常重要的进展:Llama 2可免费用于研究和商业用途。(几小时前,swyy发现它已从LLaMA 2更名为Lla
  • AI艺术欣赏体验会在上海梅赛德斯奔驰中心音乐俱乐部上演

    AI艺术欣赏体验会在上海梅赛德斯奔驰中心音乐俱乐部上演

    光影交错的镜像世界,虚实幻化的视觉奇观,虚拟偶像与真人共同主持,这些场景都出现在2019世界人工智能大会的舞台上。8月29日至31日,“AI艺术欣赏体验会”在上海
Top