网站首页 > java教程 正文
可见性
- 什么是可见性
一个线程修改共享变量后,其他线程能立即看到修改后的值的能力。
- 为什么会存在可见性问题?
- CPU 缓存架构:每个 CPU 核心有私有缓存(L1/L2),线程读写数据优先访问缓存而非主内存,修改后的数据不会立即同步到主内存或其他核心缓存
- 编译器优化:编译器可能将频繁读取的变量缓存在寄存器,导致线程无法看到内存中的最新值
- 如何解决可见性问题?
volatile 机制:写操作后强制刷新数据到主内存。读操作前使本地缓存失效,从主内存重新加载。底层通过 StoreLoad 屏障实现(如 x86 的 LOCK 前缀指令)
public class VolatileTest {
private static volatile boolean flag = false;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
System.out.println("waiting");
while (!flag) {
// do nothing
}
System.out.println("flag is true");
}).start();
Thread.sleep(2000);
new Thread(VolatileTest::setFlag).start();
}
public static void setFlag() {
System.out.println("set flag");
flag = true;
System.out.println("flag is set");
}
}
有序性
- 什么是有序性?
程序执行的顺序符合代码编写的先后顺序。
- 为什么会存在有序性问题?
- 编译器指令重排序,为优化性能调整无关指令顺序。
- 处理器乱序执行,CPU 动态调整指令执行顺序以利用流水线。
- 内存系统重排序,写缓冲区导致写操作延迟提交,失效队列导致缓存失效延迟处理。
- 如何解决有序性问题?
内存屏障禁止重排序:volatile 写前插 StoreStore 屏障,写后插 StoreLoad 屏障,synchronized 退出时插入 StoreLoad 屏障
原子性
- 什么是原子性?
一个操作不可中断地完整执行,如同瞬时完成
- 为什么会存在原子性问题?
线程切换导致的指令交错。例如:
// i++ 的非原子操作
int i = 0;
i++ // 实际分三步:
// 1. 读i到寄存器 (read)
// 2. 寄存器+1 (add)
// 3. 写回内存 (write)
- 如何解决原子性问题?
使用synchronized或者使用原子类
public class Add {
int num = 0;
public long getTotal() {
return num;
}
public synchronized void add() {
num++;
}
}
使用原子类
public class AtomicAdd {
private final AtomicInteger num = new AtomicInteger();
public long getTotal() {
return num.get();
}
public void add() {
num.incrementAndGet();
}
}
猜你喜欢
- 2025-07-19 Java AtomicInteger操作详解(java attachment)
- 2025-07-19 无锁同步-JAVA之Volatile、Atomic和CAS
- 2025-07-19 Java 作用域详解:从变量可见性到代码封装
- 2025-07-19 CompletableFuture源码分析(fragment源码分析)
- 2025-07-19 Java并发编程从入门到进阶 多场景实战
- 2025-07-19 一文搞懂 CAS 操作与 ABA 问题:高并发编程的关键知识点
- 2025-07-19 Java 内存模型、JVM 内存结构(java的内存模型)
- 2025-07-19 Java面试必备八股文(java面试必备八股文河北人社)
- 2025-07-19 Java面试都在问的CAS,你还没掌握吗?
- 2025-07-19 java VarHandle介绍(java variant)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)