您的位置:首页 > 其它

线程笔记-volatile

2016-09-23 17:33 99 查看
缓存一致性协议:最出名的就是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.csdn.net/wxwzy738/article/details/43238089

volatile与static的区别

参考:http://blog.sina.com.cn/s/blog_4e1e357d0101i486.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: