并发与并行
在并发编程领域,并行(Parallelism)和并发(Concurrency)是两个核心概念,它们既有联系又有本质区别。以下是具体分析:
1. 核心定义对比
定义 | 多个任务在 同一时刻 同时执行 | 多个任务在 同一时间段 内交替执行 |
硬件基础 | 依赖多核CPU或分布式系统 | 单核CPU即可实现 |
执行方式 | 真正的“同时执行”(物理上的并行) | 分时复用CPU(逻辑上的并行) |
典型场景 | 科学计算、GPU加速 | Web服务器、事件驱动程序 |
2. 关键区别总结
资源消耗 | 高(需多核或多机) | 低(单核即可) |
任务独立性 | 任务间无依赖(可独立运行) | 任务间可能存在协作或竞争 |
线程状态 | 线程可能同时处于Running状态 | 线程交替处于Ready/Running/BLOCKED等状态 |
性能瓶颈 | 受限于硬件核心数 | 受限于上下文切换开销 |
3. Java代码示例
并行示例(多核CPU)
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ParallelExample { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(4); // 4核CPU for (int i = 0; i < 4; i++) { executor.submit(() -> { System.out.println(Thread.currentThread().getName() + " 并行执行任务"); // 模拟耗时操作 try { Thread.sleep(1000); } catch (InterruptedException e) { } }); } executor.shutdown(); } }
并发示例(单核模拟)
public class ConcurrencyExample { public static void main(String[] args) { Thread t1 = new Thread(() -> { for (int i = 0; i < 5; i++) { System.out.println("任务1执行"); try { Thread.sleep(100); } catch (InterruptedException e) { } } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 5; i++) { System.out.println("任务2执行"); try { Thread.sleep(100); } catch (InterruptedException e) { } } }); t1.start(); t2.start(); } }
4. 应用场景
- 并行:大规模数据处理(如Hadoop MapReduce)图形渲染(GPU并行计算)加密/解密等CPU密集型任务
- 并发:Web服务器处理大量HTTP请求(如Tomcat线程池)消息队列消费者(如Kafka消费者组)游戏中的事件循环(如用户输入与AI计算交替执行)
5. 常见误区
- “并行一定比并发快”错误。若任务间存在大量同步或依赖,并行可能因锁竞争导致性能下降。
- “并发只能在多核环境下实现”错误。并发是任务调度策略,单核CPU通过分时复用也能实现。
- “Java多线程默认是并行的”错误。Java线程的并行性取决于底层硬件和线程调度器,单线程程序始终是串行的。
6. 扩展知识
- 并行化设计模式:分治算法、流水线处理
- 并发控制机制:锁(Lock)、信号量(Semaphore)、原子类(AtomicXXX)
- JVM优化:逃逸分析、锁消除(偏向锁/轻量级锁)
需要进一步了解Java并发包(java.util.concurrent
)的具体实现或性能优化策略,可以随时告诉我~
JUC编程 文章被收录于专栏
JUC 是 Java.util.concurrent 包的简称,它是 Java 5 引入的一个用于处理并发编程的工具包,为 Java 开发者提供了一系列用于高效处理并发任务的类和接口,极大地简化了多线程编程的复杂性。