Java面试题并发篇(2)

Volatile和Synchronized有什么区别?Volatile能不能保证线程安全?DCL(Double Check Lock)单例为什么要加Volatile?:


Synchronized关键字,用来加锁.Volatile只是保持变量的线程可见性.通常适用于一个线程写,多个线程读的场景.
Volatile关键字只能保证线程可见性,不能保证原子性.

    /**
     * 如果变量flag没有加volatile关键字,则线程无法读取到
     * 主线程将变量flag修改为false(可见性)
     */
    private static volatile boolean flag = true;

    public static void main(String[] args) {
        new Thread(()->{
            while (flag){

            }
            System.out.println("==========End of Thread01===========");
        }).start();

        System.out.println("true flag off");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag=false;
    }

原因分析:

在这里插入图片描述
如上图所示,所有线程的共享变量都存储在主内存中,每一个线程都有一个独有的工作内存,每个线程不直接操作在主内存中的变量,而是将主内存上变量的副本放进自己的工作内存中,只操作工作内存中的数据.当修改完毕后,再把修改后的结构放回到主内存中.每个线程都只操作自己工作内存中的变量,无法直接访问对方工作内存中的变量,线程间变量值的传递需要通过主内存来完成.
此时如果对变量加上volatile关键字修饰的话,它可以保证当A线程对共享变量的值做了变动之后,会立即刷回到主内存中,而其他线程读取到该变量的值也会作废,强迫重新从主内存中读取该变量的值,这样在任何时刻,AB线程总是会看到变量I的同一个值.


解决方案:

DCL(Double Check Lock)单例为什么要加Volatile?
Volatile另一作用,防止指令重排

    private static SingleDemo1 singleDemo1;
    
    private SingleDemo1(){}
    
    public SingleDemo1 getInstance(){
        //双重检测,对象创建重复
        if (null == singleDemo1){
            synchronized (SingleDemo1.class){
                if (null == singleDemo1){
                    singleDemo1 = new SingleDemo1();
                }
            }
        }
        return singleDemo1;
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值