Java 中的线程是并发还是并行?——深入理解 JVM 线程执行模型-java教程

java 线程本质上是**并发的**,在多核系统上可自然实现**并行执行**;jvm 本身不强制并行,但现代 jdk(包括 1.7+)通过 os 级线程映射和内核调度,使 `thread`、`forkjoinpool` 和 `threadpoolexecutor` 均能在多核环境下真正并行运行。

在 Java 中,“并发(concurrent)”与“并行(parallel)”并非互斥概念,而是存在包含关系:所有并行执行必然是并发的,但并发执行未必是并行的。

  • ✅ 并发(Concurrent):指多个线程的逻辑执行流在时间上重叠(interleaved),其事件发生顺序未严格定义(如无显式同步),强调“看起来同时进行”,依赖操作系统调度器在单核或多核上切换执行权。
  • ✅ 并行(Parallel):特指多个线程在同一时刻被物理调度到不同 CPU 核心(或硬件线程) 上真正同时执行,需满足:多核硬件 + 支持抢占式多任务的操作系统 + JVM 将 Java 线程一对一映射为 OS 线程(即 1:1 模型)。

自 Java 早期版本(JDK 1.2 起)起,主流 JVM(如 HotSpot)就已采用 1:1 线程模型:每个 java.lang.Thread 实例均对应一个由操作系统内核管理的原生线程(POSIX pthread 或 Windows thread)。这意味着:

  • 在单核系统上 → 线程表现为纯并发(时间片轮转,交替执行);
  • 在多核系统上 → 线程可被 OS 调度器分发至不同核心 → 实现真正的并行(前提是无强竞争、无阻塞、资源充足)。

? 关于 “Java 1.7 开始 ‘core-aware’” 的常见误解:
JDK 1.7 并未引入新的线程模型,也未新增“感知核心”的底层机制。所谓“core-aware”实为对 JVM 内部优化(如 ForkJoinPool 默认并行度设为 Runtime.getRuntime().availableProcessors())、垃圾收集器(如 G1 对多核更友好)及类库(如 Arrays.parallelSort()、Stream.parallel())的统称。线程能否并行,始终取决于 OS 调度能力,而非 JDK 版本本身。

各线程执行载体的实际行为对比

组件 是否并发 是否并行(多核下) 关键说明
new Thread(…).start() ✅ 是 ✅ 是(条件满足时) 直接创建 OS 线程,完全交由 OS 调度;无内置核心绑定策略,但现代 Linux/Windows 调度器天然支持跨核负载均衡。
ThreadPoolExecutor(含 Executors.newFixedThreadPool(n)) ✅ 是 ✅ 是 底层仍使用普通 Thread;若线程数 ≤ 可用核心数且任务无阻塞,高概率并行执行;注意:CachedThreadPool 创建的空闲线程可能被 OS 迁移,非绑定核心。
ForkJoinPool(默认构造 / commonPool()) ✅ 是 ✅ 是(且更智能) 默认并行度 = availableProcessors();内置工作窃取(work-stealing)机制,动态平衡多核负载;parallelStream() 和 CompletableFuture 默认使用它,是 Java 并行编程的推荐基础设施。

示例:验证并行执行(Linux/macOS 下)

public class ParallelCheck {
    public static void main(String[] args) throws InterruptedException {
        int cores = Runtime.getRuntime().availableProcessors();
        System.out.println("Available processors: " + cores);

        // 启动 cores 个计算密集型线程
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < cores; i++) {
            Thread t = new Thread(() -> {
                long sum = 0;
                // 模拟 CPU 密集型任务(避免 I/O 阻塞干扰)
                for (long j = 0; j < 10_000_000_000L; j++) {
                    sum += j & 1;
                }
                System.out.println(Thread.currentThread().getName() + " finished, sum=" + sum);
            }, "Worker-" + i);
            threads.add(t);
            t.start();
        }
        for (Thread t : threads) t.join();

        System.out.println("All threads completed.");
    }
}

✅ 在 4 核机器上运行此程序,通过 top -H 或 htop 观察线程 CPU 占用率,可清晰看到多个 Worker-* 线程同时接近 100% 占用不同核心,证实并行性。

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » Java 中的线程是并发还是并行?——深入理解 JVM 线程执行模型-java教程
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1392+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4006890+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1392+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4006891+
  • 本周更新: 0+
  • 最后更新: 2026-03-16