今天整理内存可见性相关知识点你好很高兴能帮你梳理 Java 多线程的核心知识点。写技术博客时逻辑的层层递进非常重要。我们可以从“为什么需要同步”聊到“具体的实现工具”。一、编译器优化与内存可见性在单线程环境下编译器和 CPU 会为了性能大开绿灯进行指令重排序。但在多线程环境下这往往是 Bug 的温床。1. 什么是可见性问题在 Java 内存模型JMM中每个线程都有自己的工作内存Cache而所有变量都存在主内存中。线程 A 修改了变量可能只停留在自己的工作内存。线程 B 读取的还是旧的主内存数据。2. 编译器优化指令重排为了提高执行效率编译器有时会调整代码逻辑顺序。例如// 原始代码inta1;booleanflagtrue;// 编译器可能优化为booleanflagtrue;inta1;在多线程下如果flag代表a已经准备好了这种重排就会导致另一个线程读到还没初始化的a。二、 轻量级同步锁volatile关键字volatile是 Java 提供的最轻量的同步机制。它主要有两个核心作用保证可见性一旦一个变量被声明为volatile任何线程对它的修改都会立即刷新回主内存其他线程读取时也会直接从主内存获取。禁止指令重排序通过在代码中插入“内存屏障”确保volatile变量前后的操作不会乱序。注意volatile不保证原子性比如i操作。如果需要原子性还是得靠synchronized或Atomic类。三、 线程间的“对讲机”wait()与notify()这两个方法是Object类的方法用于实现线程间的协作。wait()让当前线程进入等待状态并释放它持有的锁。notify()随机唤醒一个在该对象上等待的线程。notifyAll()唤醒所有等待线程通常更推荐更安全。核心原则它们必须在synchronized代码块内使用否则会抛出IllegalMonitorStateException。四、 终极对决wait()vssleep()这是面试中的高频题我们可以通过下表一目了然特性Object.wait()Thread.sleep()所属类来自Object类来自Thread类锁的处理会释放锁允许其他线程进入不释放锁抱着锁睡觉使用前提必须在同步块synchronized中可以在任何地方使用唤醒条件需要notify()唤醒或时间到时间到自动唤醒用途线程间通信/协作暂停执行/模拟耗时五、 实战代码示例生产者消费者模型publicclassSharedData{privateintdata;privatebooleanavailablefalse;// 消费者调用publicsynchronizedvoidconsume()throwsInterruptedException{while(!available){wait();// 没数据释放锁等着}System.out.println(消费数据: data);availablefalse;notifyAll();// 通知生产者}// 生产者调用publicsynchronizedvoidproduce(intvalue)throwsInterruptedException{while(available){wait();// 有数据还没被消费等着}datavalue;availabletrue;System.out.println(生产数据: data);notifyAll();// 通知消费者}} 结语理解 Java 多线程的关键在于理解内存模型和锁的机制。volatile解决了“看得到”的问题而synchronized与wait/notify解决了“排队与协作”的问题。