多线程并发和并行的区别

背景

 对于java开发从业人员来说,并发编程是绕不开的话题,juc并发包下提供了一系列多线程场景解决方案。
 随着jdk1.8的普及,多线程处理问题,除了使用使用线程池(ExecutorService),很多人选择了parallelStream() 并行流,底层使用forkjoin实现并行处理。
 那么并行和并发又有什么区别?究竟改如何选择?滥用时又会有什么影响?
  这些问题我分以下几篇文章进行详细说明:
  1. 多线程并发和并行的区别 (本文)
  2. parallelStream()并行滥用的后果
  3. forkjoin和forkjoinpool讲解
  4. 线程池正确用法

并发和并行共同点

  • 都利用多线程技术
  • 目的都是提高CPU的使用率

并发和并行区别

侧重点不同

  • 并发(concurrency):强调一个处理器同时处理多个任务,并不是正在同时运行。
  • 并行(parallelism):强调多个处理器或者是多核的处理器同时处理多个不同的任务,同时运行多段代码
    在这里插入图片描述

使用场景不同

  • io密集场景
    场景应用程序开发,提供http接口、数据库查询、微服务调用都是io请求,io等等时几乎不消耗cpu,这是为了提供cup使用率,建议使用多线程并发,线程数可以远大于cpu核数。
  • cup密集场景
    对应大量的加减乘除运算、md5、hash等运算操作,需要持续使用cpu,需要让多核cpu并行运算,适合使用forkjoin并行计算。
    技术场景多线程不足,使用多线程技术,也能提高性能,但是线程设置过大会浪费cpu线程切换的时间,如果线程任务分配不均匀,会导致有的cpu忙碌有的cpu空闲

技术栈不同

  • 并发编程
    jdk1就支持多线程Thread
    jdk5加入Thread pool和juc
    这些都是对多线程的支持,多线程代码可以单核cpu和多核cpu机器上,使用多线程可以在io并发高时,有效利用cpu资源。
  • 并行编程
    jdk7加入fork-join库
    jdk8加人parallelstream
    这些是对并行计算的支持,目的是同时使用多核cpu进行高效计算
### 线程并发并行的概念 并发(Concurrency)指在同一时间段内,多个任务交替执行,强调任务之间切换,关注逻辑结构。即在一段时间内宏观上有多个程序在同时运行,但在单核处理器中,每一时刻仅能有一道程序执行,微观上这些程序只能分时地交替执行。若操作系统中有多个CPU,这些可并发执行的程序便可被分配到多个处理机上实现并行执行。 并行(Parallelism)指在同一时刻,多个任务同时执行,依赖多核CPU,多个线程真正同时运行,即利用每个处理机来处理一个可并发执行的程序,多个程序可以同时执行[^1][^2]。 ### 线程并发并行区别 - **侧重点**:并发强调一个处理器同时处理多个任务,并非正在同时运行;并行强调多个处理器或者多核处理器同时处理多个不同的任务,同时运行多段代码[^3]。 - **执行场景**: - **并发**:在单核CPU上的多线程并发,即任务切换执行;在IO密集场景,如应用程序开发提供http接口、数据库查询、微服务调用等IO请求,IO等待时几乎不消耗CPU,为提高CPU使用率,建议使用多线程并发线程数可远大于CPU核数。 - **并行**:若操作系统中有多个CPU,可将并发执行的程序分配到多个处理机上实现并行执行;在CPU密集场景,对应大量的加减乘除运算、md5、hash等运算操作,需要持续使用CPU,适合使用fork - join并行计算让多核CPU并行运算[^1][^3]。 - **资源利用**:并发是在时间上复用CPU资源,通过任务切换实现多个任务在一段时间内都有进展;并行是在空间上利用多个CPU核心同时处理多个任务,充分发挥多核CPU的能力。 - **技术栈**: - **并发编程**:JDK1就支持多线程Thread,JDK5加入Thread pooljuc,多线程代码可在单核CPU多核CPU机器上使用,在IO并发高时,能有效利用CPU资源。 - **并行编程**:JDK7加入fork - join库,JDK8加入parallelStream,目的是同时使用多核CPU进行高效计算[^3]。 ### 相关代码示例 #### 并发示例(Java) ```java class ConcurrencyExample { public static void main(String[] args) { Runnable task1 = () -> { for (int i = 0; i < 5; i++) { System.out.println("Task 1: " + i); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }; Runnable task2 = () -> { for (int i = 0; i < 5; i++) { System.out.println("Task 2: " + i); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread thread1 = new Thread(task1); Thread thread2 = new Thread(task2); thread1.start(); thread2.start(); } } ``` #### 并行示例(Java) ```java import java.util.Arrays; import java.util.List; class ParallelExample { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); numbers.parallelStream() .forEach(num -> System.out.println(Thread.currentThread().getName() + ": " + num)); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值