当前位置: 首页 > news >正文

第1部分-并发编程基础与线程模型

第1部分:并发编程基础与线程模型

核心目标

理解并发的概念、Java的线程机制与底层原理。


1. 并发 vs 并行

并发(Concurrency)

  • 定义:多个任务在同一个时间段内交替执行,但在任意时刻只有一个任务在执行
  • 特点:通过时间片轮转实现多任务"同时"执行
  • 适用场景:I/O密集型任务,如网络请求、文件读写

并行(Parallelism)

  • 定义:多个任务在同一时刻真正同时执行
  • 特点:需要多核CPU支持,任务真正并行运行
  • 适用场景:CPU密集型任务,如数学计算、图像处理

对比示例

// 并发示例:单核CPU上的多线程
public class ConcurrencyExample {public static void main(String[] args) {// 两个线程在单核上交替执行new Thread(() -> System.out.println("任务1")).start();new Thread(() -> System.out.println("任务2")).start();}
}// 并行示例:多核CPU上的多线程
public class ParallelismExample {public static void main(String[] args) {// 两个线程在多核上真正同时执行IntStream.range(0, 2).parallel().forEach(i -> System.out.println("并行任务" + i));}
}

2. 进程与线程的区别

进程(Process)

  • 定义:操作系统进行资源分配和调度的基本单位
  • 特点
    • 拥有独立的内存空间
    • 进程间通信需要特殊机制(IPC)
    • 创建和销毁开销大
    • 进程间相互独立,一个进程崩溃不影响其他进程

线程(Thread)

  • 定义:CPU调度和执行的基本单位,是进程内的执行单元
  • 特点
    • 共享进程的内存空间
    • 线程间通信简单(共享变量)
    • 创建和销毁开销小
    • 一个线程崩溃可能影响整个进程

对比表

特性进程线程
内存空间独立共享
通信方式IPC共享变量
创建开销
切换开销
安全性

3. Java线程生命周期与状态

线程状态枚举(Thread.State)

public enum State {NEW,           // 新建状态RUNNABLE,      // 可运行状态BLOCKED,       // 阻塞状态WAITING,       // 等待状态TIMED_WAITING, // 超时等待状态TERMINATED     // 终止状态
}

状态详解

NEW(新建状态)
  • 线程对象创建后,调用start()方法之前
  • 此时线程还未开始执行
RUNNABLE(可运行状态)
  • 调用start()方法后,线程进入此状态
  • 包括正在运行和等待CPU调度两种情况
  • 在Java中,阻塞I/O不会改变线程状态为BLOCKED
BLOCKED(阻塞状态)
  • 线程等待获取同步锁时进入此状态
  • 当锁被释放时,线程重新进入RUNNABLE状态
WAITING(等待状态)
  • 调用wait()join()LockSupport.park()等方法
  • 需要其他线程调用notify()notifyAll()等方法唤醒
TIMED_WAITING(超时等待状态)
  • 调用sleep()wait(timeout)join(timeout)等方法
  • 在指定时间后自动唤醒
TERMINATED(终止状态)
  • 线程执行完毕或异常退出
  • 无法再次启动

状态转换图

NEW → RUNNABLE → BLOCKED → RUNNABLE↓        ↓↓    WAITING ← RUNNABLE↓        ↓↓    TIMED_WAITING ← RUNNABLE↓        ↓↓    TERMINATED ← RUNNABLE

4. Java内存模型(JMM)简介

三大特性

原子性(Atomicity)
  • 定义:一个操作不可被中断,要么全部执行,要么全部不执行
  • 保证方式:synchronized、Lock、原子类
  • 示例
// 非原子操作
int i = 0;
i++; // 实际包含:读取i、计算i+1、写入i// 原子操作
AtomicInteger atomicI = new AtomicInteger(0);
atomicI.incrementAndGet(); // 原子操作
可见性(Visibility)
  • 定义:一个线程对共享变量的修改,其他线程能够立即看到
  • 问题原因:CPU缓存、指令重排序
  • 保证方式:volatile、synchronized、Lock、final
  • 示例
// 可见性问题
class VisibilityProblem {private boolean flag = false; // 可能不可见public void setFlag() {flag = true; // 其他线程可能看不到}public void checkFlag() {while (!flag) {// 可能永远循环}}
}// 解决方案
class VisibilitySolution {private volatile boolean flag = false; // volatile保证可见性public void setFlag() {flag = true; // 其他线程能立即看到}public void checkFlag() {while (!flag) {// 能正常退出循环}}
}
有序性(Ordering)
  • 定义:程序执行的顺序按照代码的先后顺序执行
  • 问题原因:指令重排序优化
  • 保证方式:volatile、synchronized、Lock、happens-before规则

JMM结构

┌─────────────────────────────────────────┐
│              主内存 (Main Memory)        │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │ 变量A   │ │ 变量B   │ │ 变量C   │   │
│  └─────────┘ └─────────┘ └─────────┘   │
└─────────────────────────────────────────┘↑                    ↑│                    │┌─────────────┐    ┌─────────────┐│ 线程1工作内存 │    │ 线程2工作内存 ││ ┌─────────┐ │    │ ┌─────────┐ ││ │ 变量A副本│ │    │ │ 变量A副本│ ││ └─────────┘ │    │ └─────────┘ │└─────────────┘    └─────────────┘

5. 上下文切换与线程调度机制

上下文切换(Context Switch)

  • 定义:CPU从一个线程切换到另一个线程时,需要保存和恢复线程的状态信息
  • 开销:包括保存/恢复寄存器、程序计数器、栈指针等
  • 优化:减少线程数量、使用线程池、避免不必要的同步

线程调度机制

抢占式调度(Preemptive Scheduling)
  • 特点:操作系统决定何时切换线程
  • 优点:响应性好,防止单个线程独占CPU
  • 缺点:切换开销大
协作式调度(Cooperative Scheduling)
  • 特点:线程主动让出CPU控制权
  • 优点:切换开销小,可预测性好
  • 缺点:可能导致线程饥饿

Java线程调度

// 线程优先级设置(1-10,默认为5)
Thread thread = new Thread(() -> {// 线程任务
});
thread.setPriority(Thread.MAX_PRIORITY); // 10
thread.setPriority(Thread.MIN_PRIORITY); // 1
thread.setPriority(Thread.NORM_PRIORITY); // 5

6. Java 21中的线程模型演进

传统线程模型

  • 特点:1:1映射(一个Java线程对应一个操作系统线程)
  • 问题
    • 创建线程开销大(约2MB栈空间)
    • 上下文切换成本高
    • 线程数量受限于操作系统

虚拟线程(Virtual Threads)

  • 特点:M:N映射(多个虚拟线程映射到少量平台线程)
  • 优势
    • 创建开销极小(约几KB)
    • 支持百万级线程
    • 自动调度,无需手动管理

虚拟线程示例

// Java 21 虚拟线程创建
public class VirtualThreadExample {public static void main(String[] args) {// 方式1:直接创建Thread virtualThread = Thread.ofVirtual().name("virtual-thread").start(() -> {System.out.println("虚拟线程执行中...");});// 方式2:使用线程池try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {executor.submit(() -> {System.out.println("虚拟线程池任务执行中...");});}}
}

平台线程 vs 虚拟线程对比

特性平台线程虚拟线程
创建开销大(~2MB)小(~几KB)
数量限制数千个数百万个
调度方式操作系统JVM
适用场景CPU密集型I/O密集型
阻塞成本

实践练习

练习1:观察线程状态变化

public class ThreadStateObserver {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {try {Thread.sleep(2000);synchronized (ThreadStateObserver.class) {// 模拟等待锁}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});System.out.println("创建后: " + thread.getState()); // NEWthread.start();System.out.println("启动后: " + thread.getState()); // RUNNABLEThread.sleep(100);System.out.println("运行中: " + thread.getState()); // RUNNABLEThread.sleep(3000);System.out.println("结束后: " + thread.getState()); // TERMINATED}
}

练习2:并发vs并行性能测试

public class ConcurrencyVsParallelism {public static void main(String[] args) {int[] array = IntStream.range(0, 1000000).toArray();// 串行执行long start = System.currentTimeMillis();int sum1 = Arrays.stream(array).sum();long serialTime = System.currentTimeMillis() - start;// 并行执行start = System.currentTimeMillis();int sum2 = Arrays.stream(array).parallel().sum();long parallelTime = System.currentTimeMillis() - start;System.out.println("串行结果: " + sum1 + ", 耗时: " + serialTime + "ms");System.out.println("并行结果: " + sum2 + ", 耗时: " + parallelTime + "ms");}
}

总结

本部分介绍了Java并发编程的基础概念:

  1. 并发与并行:理解多任务执行的不同方式
  2. 进程与线程:掌握操作系统的基本概念
  3. 线程状态:了解Java线程的完整生命周期
  4. 内存模型:理解并发问题的根本原因
  5. 调度机制:掌握线程调度的原理
  6. 虚拟线程:了解Java 21的线程模型革新

这些基础知识为后续深入学习并发编程奠定了坚实的基础。下一部分将学习线程的创建与管理。

http://www.dtcms.com/a/511091.html

相关文章:

  • 【含文档+PPT+源码】基于SSM的智能驾校预约管理系统
  • python股票交易数据管理系统 金融数据 分析可视化 Django框架 爬虫技术 大数据技术 Hadoop spark(源码)✅
  • 有哪些网站可以自己做加视频做一个购物网站
  • 佛山建站公司模板开发一个物流app需要多少钱
  • Java——使用Aspose实现docx模板填充与导出word和pdf
  • Cef笔记:VS2019编译cef_109.0.5414
  • 云上极速转码:阿里云ECS+T4 GPU打造高性能FFmpeg视频处理引擎(部署指南)
  • Mysql 数据库迁移
  • 自建webrtc低延时分布式街机游戏直播方案
  • PHP四川文旅服务网站-计算机毕业设计源码76050
  • 从“开源开放”走向“高效智能”:阿里云 EMR 年度重磅发布
  • AI服务器工作之ubuntu系统下的驱动安装
  • 将跨平台框架或游戏引擎开发的 Windows 应用上架 Microsoft Store
  • 网站建立需要什么永久网站建设教程
  • 安装nginx
  • Leetcode+Java+图论+最小生成树拓扑排序
  • Unity画线功能LineRenderer详解附有案例
  • 从零部署自维护版 Uptime Kuma:Node.js + PM2 + Nginx 全链路实战指南
  • 哪个网站可以做纸箱沈阳市住房和城乡建设部网站
  • 腾讯送命题:手写多头注意力机制。。。
  • 信息传递视角下开源AI智能名片链动2+1模式S2B2C商城小程序对零售企业的赋能研究
  • AWS IoT Core 自动化巡检工具开发与实战报告
  • 【开题答辩过程】以《重庆市社区养老服务小程序设计与实现》为例,不会开题答辩的可以进来看看
  • 思淘网站建设网站域名证书
  • Substance Designer的通道合并(Channel Packing)自动化工作流
  • 【数据分析】基于R语言的宏基因组微生物群落下游数据的统计分析与可视化教程
  • TDE透明加密技术原理深度解析与文件在线安全传输实践指南
  • AI协作天花板!CherryStudio让多模型协同像搭积木
  • flash网站开发用什么语言wordpress 静态文件大
  • 小游戏引擎架构设计案例分析