缓存一致性协议:最出名的就是Intel 的MESI协议,MESI协议保证了每个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。
volatile:当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。
一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
在有限的一些情形下使用 volatile 变量替代锁。要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:
1)对变量的写操作不依赖于当前值。
2)该变量没有包含在具有其他变量的不变式中。
package thread.basic._volatile.demo2;
public class Volatile2 extends Object implements Runnable {
//value变量没有被标记为volatile
private int value;
//missedIt变量被标记为volatile
private volatile boolean missedIt;
public Volatile2() {
value = 0;
missedIt = false;
}
public void run() {
System.out.println(Thread.currentThread().toString()+"..entering run()");
//循环检查value的值是否不同
while ( missedIt ) {
System.out.println(Thread.currentThread().toString()+"..printing..."+value++);
}
System.out.println(Thread.currentThread().toString()+"..leaving run()");
}
public void setStop(){
missedIt = false;
}
public void setStart(){
missedIt = true;
}
public static void main(String[] args) {
try {
//通过该构造函数可以获取实时时钟的当前时间
Volatile2 vol = new Volatile2();
Thread t = new Thread(vol);
Thread t2 = new Thread(vol);
Thread t3 = new Thread(vol);
vol.setStart(); //设置关闭
t.start();
// Thread.sleep(10);
// vol.setStop();
t2.start();
Thread.sleep(10);
vol.setStop();
t3.start();
} catch ( InterruptedException x ) {
System.err.println("one of the sleeps was interrupted");
}
}
}
volatile的原理和实现机制
前面讲述了源于volatile关键字的一些使用,下面我们来探讨一下volatile到底如何保证可见性和禁止指令重排序的。
下面这段话摘自《深入理解Java虚拟机》:
“观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”
lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
2)它会强制将对缓存的修改操作立即写入主存;
3)如果是写操作,它会导致其他CPU中对应的缓存行无效。
**注意:**volatile通常某个操作的完成、发生中断或状态的标示,不能确保操作的原值行(例如:i++)。
单例设计模式:
class Singleton{
private volatile static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if(instance==null) {
synchronized (Singleton.class) {
if(instance==null)
instance = new Singleton();
}
}
return instance;
}
}
参考:http://www.cnblogs.com/dolphin0520/p/3920373.html
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
经典:http://blog.youkuaiyun.com/wxwzy738/article/details/43238089
volatile与static的区别
参考:http://blog.sina.com.cn/s/blog_4e1e357d0101i486.html

本文详细解析了Intel MESI缓存一致性协议的工作原理,并深入介绍了volatile关键字的作用及其实现机制,包括保证可见性和禁止指令重排序等特性。
1222

被折叠的 条评论
为什么被折叠?



