您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Java线程安全的三大核心是什么
## 引言
在多线程编程中,线程安全(Thread Safety)是保证程序正确性的核心要素。Java作为一门广泛使用的多线程编程语言,其线程安全机制尤为重要。本文将深入探讨**Java线程安全的三大核心**:**原子性(Atomicity)**、**可见性(Visibility)**和**有序性(Ordering)**,并通过代码示例和底层原理分析帮助开发者构建高并发安全的应用。
---
## 一、原子性(Atomicity)
### 1.1 什么是原子性?
原子性是指一个操作是不可分割的整体,要么全部执行成功,要么完全不执行。在多线程环境下,原子性保证线程不会因上下文切换导致操作被中断。
### 1.2 非原子性操作的隐患
```java
public class Counter {
private int count = 0;
public void increment() {
count++; // 非原子操作
}
}
count++
实际包含三个步骤:读取值、修改值、写入值。多线程并发时可能导致结果错误。
public synchronized void increment() {
count++;
}
AtomicInteger
基于CAS(Compare-And-Swap)实现无锁原子操作:
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
CMPXCHG
)实现无锁并发。当一个线程修改共享变量后,其他线程能立即看到修改后的值。由于CPU缓存的存在,线程可能读取到过时数据。
public class VisibilityDemo {
private boolean flag = true; // 无可见性保证
public void run() {
while (flag) {} // 可能死循环
System.out.println("Thread stopped");
}
public void stop() {
flag = false;
}
}
即使主线程调用stop()
,子线程可能因缓存一致性问题无法感知flag
变化。
private volatile boolean flag;
public synchronized void stop() {
flag = false;
}
程序执行的顺序按照代码的先后顺序执行。但编译器和处理器可能进行指令重排序优化。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 步骤1
synchronized (Singleton.class) { // 步骤2
if (instance == null) { // 步骤3
instance = new Singleton(); // 步骤4
}
}
}
return instance;
}
}
上述双重检查锁(DCL)在未加volatile时可能因重排序返回未初始化的对象。
private volatile static Singleton instance;
public class SafeCounter {
private volatile int count = 0; // 可见性
private final AtomicInteger atomicCount = new AtomicInteger(0);
public synchronized void incrementSync() { // 原子性+有序性
count++;
}
public void incrementAtomic() {
atomicCount.incrementAndGet(); // CAS原子操作
}
}
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton(); // volatile禁止重排序
}
}
}
return instance;
}
}
核心特性 | 问题场景 | 解决方案 | 实现原理 |
---|---|---|---|
原子性 | 竞态条件(Race Condition) | synchronized/Atomic/CAS | 锁机制、CPU指令 |
可见性 | 缓存不一致 | volatile/synchronized | 内存屏障、MESI协议 |
有序性 | 指令重排序 | volatile/happens-before | 内存屏障、JMM规范 |
理解并合理运用这三大核心,是构建高并发Java应用的基础。开发者需根据具体场景选择合适方案,平衡性能与安全性。
扩展阅读:
- 《Java并发编程实战》
- JSR-133: Java Memory Model and Thread Specification “`
注:本文实际约2100字,包含代码示例、原理分析和表格总结,符合Markdown格式要求。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。