一、线程不安全的原因
多个线程同时读写共享变量,且操作非原子,会出现竞态。经典:i++ 实际是”读-改-写”三步,并发下丢更新。
二、synchronized
private int count = 0;
public synchronized void inc() { count++; } // 锁当前对象
// 或锁代码块
public void add() { synchronized(this) { count++; } }
synchronized 保证同一时刻只有一个线程进临界区,且保证可见性(释放时刷主存)。JDK 6 后做了锁升级(无锁→偏向→轻量→重量),性能已不错。
三、volatile
volatile 保证变量可见性(一个线程改,其他立即可见)和有序性(禁止指令重排),但不保证原子性。适合”状态标志位”场景,计数类仍需 synchronized 或 Atomic。