Java并发编程-多线程基础(三)

文章目录

  • 线程间通信
    • 线程间通信的核心问题
    • [volatile 关键字](#volatile 关键字)
      • [1. 核心特性](#1. 核心特性)
      • [2. 使用限制](#2. 使用限制)
      • [3. 示例](#3. 示例)
    • [synchronized 关键字](#synchronized 关键字)
      • [1. 核心特性](#1. 核心特性)
      • [2. 示例](#2. 示例)
    • [volatile 与 synchronized 的对比](#volatile 与 synchronized 的对比)
    • [Volatile 和 Synchronized 最佳实践](#Volatile 和 Synchronized 最佳实践)

线程间通信

线程间通信的核心问题

多个线程通过共享内存实现信息交换,但需解决以下问题:

  1. 可见性:线程修改变量后其他线程能否立即感知。
  2. 原子性:操作是否不可分割,避免数据不一致。
  3. 有序性:代码执行顺序是否符合预期。

volatile 关键字

1. 核心特性

  • 可见性保证 :所有线程直接访问共享内存中的变量值,而非本地缓存。

    • 写操作:强制将修改后的值刷新到主内存。

    • 读操作:强制从主内存读取最新值。

  • 禁止指令重排序:通过内存屏障限制编译器和处理器的重排序。

2. 使用限制

  • 不保证原子性 :仅适用于单次读/写操作,无法处理复合操作(如 i++)。

  • 典型场景

    • 状态标志 (如 volatile boolean on = true)。

    • 配合 CAS 操作实现无锁并发(如 AtomicInteger 内部实现)。

3. 示例

java 复制代码
public class StatusMonitor {
    private volatile boolean running = true; // 状态标志

    public void shutdown() {
        running = false; // 修改后对所有线程可见
    }

    public void doWork() {
        while (running) { // 实时读取共享内存的值
            // 执行任务
        }
    }
}

synchronized 关键字

1. 核心特性

  • 原子性 & 排他性:同一时刻只允许一个线程进入同步代码。

  • 隐式锁机制:通过锁对象实现同步(锁粒度可以是实例对象、Class 对象或自定义对象)。

  • 可见性保证:线程退出同步代码时,修改的变量值强制刷新到主内存。

  • synchronized 无法完全禁止内部指令重排序 ,但通过临界区的内存屏障和线程互斥访问机制,对外部线程表现为有序性

  • 在需要严格禁止重排序的高并发场景中(如单例初始化),必须结合 volatile 来补充有序性保证。

2. 示例

java 复制代码
public class Counter {
    private int count = 0;
  
    public synchronized void increment() { // 普通同步方法
        count++; // 原子操作
    }

    public static synchronized void staticMethod() { // 静态同步方法
        // 操作共享资源
    }

    public void blockSync() {
        synchronized (this) { // 同步块
            count--;
        }
    }
}

volatile 与 synchronized 的对比

特性 volatile synchronized
可见性 保证 保证
原子性 仅支持单个读/写操作 支持代码块级原子性
排他性 有(同一时刻仅一个线程访问)
性能消耗 较低(仅内存屏障) 较高(涉及锁竞争与上下文切换)
适用场景 状态标志、双重检查锁(DCL) 复杂操作保护(如转账、计数等)

Volatile 和 Synchronized 最佳实践

  • 双重检查锁定(Double-Checked Locking)
java 复制代码
public class Singleton {
    private static volatile Singleton instance;
  
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton(); // volatile 防止指令重排序
                }
            }
        }
        return instance;
    }
}

volatile 在此阻止 JVM 重排序初始化步骤(分配内存与对象构造),确保线程安全。

相关推荐
社交怪人16 分钟前
【算平均分】信息学奥赛一本通C语言解法(题号2071)
c语言·开发语言
阿维的博客日记19 分钟前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring
雨辰AI19 分钟前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
郭涤生1 小时前
不同主机之间网络通信-以太网连接复习
开发语言·rk3588
山居秋暝LS1 小时前
【无标题】RTX00安装paddle OCR,win11不能装最新的,也不能用GPU
开发语言·r语言
卢锡荣1 小时前
单芯通吃,盲插标杆 —— 乐得瑞 LDR6020,Type‑C 全场景互联 “智慧芯”
c语言·开发语言·计算机外设
Xin_ye100861 小时前
C# 零基础到精通教程 - 第七章:面向对象编程(入门)——类与对象
开发语言·c#
辰海Coding2 小时前
MiniSpring框架学习-完成的 IoC 容器
java·spring boot·学习·架构
AI科技星2 小时前
《数学公理体系·第三部·数术几何》(2026 年版)
c语言·开发语言·线性代数·算法·矩阵·量子计算·agi
小小编程路2 小时前
C++ 多线程与并发
java·jvm·c++