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;
    }

}

  

 

posted @ 2021-01-27 14:12  mxn0829  阅读(50)  评论(0)    收藏  举报