volatile
volatile
轻量级同步机制。
volatile保证了可见性,不保证原子性,保证了有序性(禁止指令重排)。
*可见性:java全局变量存在主内存,线程运行时把变量值拷贝到自己的工作内存在操作,操作完成在写回主内存。线程之间的工作内存互相是不可见的,volatile关键字修饰的变量,保证了可见性,即某线程修改了主内存值,其他线程可以及时拿到最新值。
*不保证原子性:原子性是指数据的完整一致性,不可分割,操作数据要么同时成功要么同时失败!多线程操作数值加加操作时,不加锁volatile修饰不能保证原子性。
解决方法(1)加synchronized加锁。但是效率低(2)使用原子类AtomicInteger
*禁止指令重排:jvm虚拟机对于没有依赖性的代码,会进行优化重排。比如instance = new SingletonDemo()经过汇编会变成三句,其中没有依赖关系的语句就有可能会发生重排。
单线程情况下没有数据安全问题,多线程情况下可能会发生数据安全问题。
Volatile使用场景:多线程情况下的单例模式
代码示例:
public class SingletonDemo {
private static volatile SingletonDemo instance = null;//添加volatile关键字,禁止指令重拍
private SingletonDemo(){
System.out.println("实例初始化....");
}
public static SingletonDemo getinstance(){
//DCL双端检索
if(instance == null){
synchronized(SingletonDemo.class){
if(instance == null){
instance = new SingletonDemo();
}
}
}
return instance;
}
public static void main(String[] args){
/*new Thread(() -> {
System.out.print("1");
},1).start();*/
for(int i = 0 ;i<1000;i++){
ThreadDemo td = new ThreadDemo();
new Thread(td).start();
}
}
}
public class ThreadDemo implements Runnable{
private boolean flag = false;
public void run(){
/*try{
// 该线程 sleep(200), 导致了程序无法执行成功
Thread.sleep(200);
}catch(InterruptedException e){
e.printStackTrace();
}
flag = true;
System.out.println("flag="+isFlag());*/
SingletonDemo.getinstance();
}
public boolean isFlag(){
return flag;
}
public void setFlag(boolean flag){
this.flag = flag;
}
}
浙公网安备 33010602011771号