(每日一题)Volatile到底有什么作用?

今天在牛客上看到一个面经,这一个人在面试之后的总结,我在里面看一个题目非常有意思,今天自己记录一下。

首先我感觉这个面试官水平非常高,他面试,是循序渐进的,例如:他今天面试的这个,就是一步步扩展知识面一步步引导面试生,由项目引出里氏替换原则(是一种软件设计原则),然后继续引出什么是单例模式?接着要他手写一个单例模式

    //手写单例模式(懒汉式)
    private static Singleton getSingleton(){
        //这里的 new Singleton 真的不会实例多次吗?(多线程情况下)
        if (singleton==null){
            singleton = new Singleton();
        }
        return singleton;
    }

就上面代码中说出的这个问题,我们最先想到的是synchronized 上锁

    private synchronized static Singleton getSingleton(){
        //这里的 new Singleton 真的不会实例多次吗?(多线程情况下)
        if (singleton==null){
            singleton = new Singleton();
        }
        return singleton;
    }
这里的synchronized锁的是对象还是方法或者是代码块?

不管这synchronized放在这个方法上还是放在这个方法内部,都是锁的对象。

锁的是对象,又因为这是个静态方法 ,所以调用者自然是这个类。

所以synchronized这样上锁肯定会造成性能问题,在变通一下,我们把这个synchronized放在真正产生冲突处.

private static Singleton getSingleton(){
        if (singleton==null){
            synchronized (Singleton.class{
                singleton = new Singleton();
            }
        }
        return singleton;
    }

又产生一个问题,多线程情况下,两个线程A线程B线程,A线程发现这个对象没有new,他直接new出来,B线程,同事也发现这个对象没有new,又new了一遍。

解决方法:

 private static Singleton getSingleton(){
        if (singleton==null){
            synchronized (Singleton.class){
                if (singleton==null){
                    singleton = new Singleton();
                }
            }

        }
        return singleton;
    }

这个时候为了保证线程安全问题,双重检测模型,实现单例模式。

这个时候volatile出现了,它的出现能解决什么问题?

volatile修饰的属性,它是属性修饰符,你方法上不行。大家都知道这个属性,是一个成员变量,那既然是一个变量,是一块内存空间,那么说给这个,内存空间加上volatile有两个特点。

  1. 它的作用是可以解决一个可见性的问题

  1. 防止指令重排序问题

下面这两个问题,我来画图说一下

第一个问题

下面三个方块你可以认为是三个线程,第一个线程 在拿到属性a然后将属性变为1,然后其他两个线程,看到却还是a=0

加上volatile 后相当于告诉其他两个线程这个属性的只要变成a=1,这就是解决了属性的可见性问题。

第二个问题是,也就是我们刚才的问题,单例的时候对象创建的问题,创建我们给了一行指令

new Singleton();

1、发一个new 指令,申请一个空间

2、加载空间内部信息
3、执行构造方法

4、告知对象构建成功(返回地址引用给你)

启动因为2,3 步骤比较慢,CPU会做一个性能优化,就是这两个步骤可以,来回交换顺序的。

也就是说我现在要买一个房子,A同事说我这有好屋推荐,B同事也说,有好房子推荐,但是呢A同事是等房子装修好,并且内部摆设都弄好了,才准备把钥匙给我,B同事,说我先把钥匙给你,我再装修内部,这时候A同事也要给我钥匙,是不是造成了指令2重排了。

volatile就解决了这个种指令重排序问题。

好的,这是就是我今天的总结,如果,讲的有问题,欢迎大家指出来!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值