synchronized 关键字如何保证变量的可见性?请说明实现机制。
是的,synchronized
既保证了原子性,也保证了可见性。
在Java内存模型中,所有的变量都存储在主内存中,每个线程都有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝。线程对变量的所有操作(读取、赋值)都必须在工作内存中进行,而不能直接读写主内存中的数据。不同线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递需要通过主内存来完成。
synchronized
的可见性是通过对一个线程修改后的变量的值进行同步,从而使其他线程能够看到修改后的值。
具体实现上,当一个线程进入synchronized
同步代码块时,同步代码块内部的变量会从主内存中读取到工作内存。当线程释放锁时,同步代码块内部的新值会被刷新回主内存。当另一个线程进入同步代码块时,可以看到之前已经被刷新回主内存的变量的新值。
这样,通过synchronized
,不同的线程能够及时地看到共享变量的最新值,从而达到可见性。
例如:
public class MyClass {
private int count = 0;
public synchronized void increase() {
count++;
}
public synchronized int getCount() {
return count;
}
}
在这个例子中,increase
方法和getCount
方法都是synchronized
方法,它们锁的是同一个对象(MyClass的对象)。当一个线程通过increase
方法改变count
的值后,这个新值会在方法结束时刷新回主内存。当另一个线程通过getCount
方法获取count
的值时,会从主内存中读取最新的值,从而保证了可见性。