一、volatile 关键字:当多个线程进行操作共享数据时,可以保证内存中的数据可见。
相较于 synchronized 是一种较为轻量级的同步策略。
/*TestVolatile.java*/
public class TestVolatile {
public static void main(String[] args) {
ThreadDemo td = new ThreadDemo();
new Thread(td).start();
while(true){
if(td.isFlag()){
System.out.println("------------------");
break;
}
}
//输出:
//flag=true
}
}
class ThreadDemo implements Runnable {
private volatile Boolean flag = false;
@Override
public void run() {
try {
Thread.sleep(200);
}
catch (InterruptedException e) {
}
flag = true;
System.out.println("flag=" + isFlag());
}
public Boolean isFlag() {
return flag;
}
public void setFlag(Boolean flag) {
this.flag = flag;
}
}
说明:如图
在程序执行时,JVM会给线程分配独立的内存空间,线程1更改flag值的时候,是在自己的内存中先更改,之后才传回主存中更改主存的flag值,又因while(true)循环的效率太高,main线程来不及再去主存中读数据,因此一直取的是flag=false;这种问题称为内存可见性问题:当多个线程操作共享数据时,彼此不可见。
synchronize虽然能解决这个问题,但是效率太低;volatile修饰的都在主存中完成,即不在为每个线程单独拷贝数据,虽然同样降低了性能,但是比锁的效率高。
synchronize与volatile的区别:
注意:
1. volatile 不具备“互斥性”
2. volatile 不能保证变量的“原子性”(不可分割性,下篇解释“原子性”)