首页 > 其他分享 >单例模式为什么要加volatile修饰?

单例模式为什么要加volatile修饰?

时间:2023-02-04 10:44:14浏览次数:39  
标签:要加 SingleTonDemo02 模式 volatile 内存 单例 懒汉

单例模式为什么要加volatile来修饰?
解析:
这里我们自己应该要先搞清楚面试官问的到底是什么?因为单例模式有四种实现:饿汉模式,懒汉模式,静态内部类,枚举 搞清楚问的是哪一种,其实只要自己都会写的话 就很清楚的
知道这里问的是懒汉模式的变量为什么要用volatile来修饰?
搞清楚了问的是什么,接下来就要明白懒汉模式的具体实现到底是什么样的?

懒汉模式的实现代码(Coding):

/**
 * 懒汉模式:指的不是类加载就开始创建,它是延迟加载的,指正在调用使用单例实例的时候才开始创建
 */
public class SingleTonDemo02 {
    // 1、私有化构造器
    private SingleTonDemo02(){}
    // 2、定义静态变量 懒汉模式的这个变量需要用volatile来修饰(原因的话后面再说)
    private static volatile SingleTonDemo02 singleTonDemo02 = null;
    // 3、公开获取INSTANCE(单例实例)的方法
    public static SingleTonDemo02 getInstance() {
        // 先创建 要考虑高并发的情况 因此采用双重校验锁和volatile来保证线程安全
        if (singleTonDemo02 == null) { // 第一次校验
            // 上锁
            synchronized (SingleTonDemo02.class) {
                if (singleTonDemo02 == null) { // 第二次校验
                    // 才开始创建
                    singleTonDemo02 = new SingleTonDemo02();
                }
            }
        }
        return singleTonDemo02;
    }
}

我们会发现懒汉模式 它实现的时候 本身就用两次的if和synchronized来保证线程安全性 那为什么还要给变量加上volatile来修饰?

搞清楚问题前 我们应该先知道volatile到底有什么作用!简单来说:volatile有两个作用:1、解决内存可见性问题 2、防止指令重排

具体来说:

在并发环境下 有三大特性:原子性、有序性、可见性。而内存可见性问题 就是指多个线程操作同一个变量 如果某个线程修改了该变量 那其他线程是感应不到的,这就是内存可见性问题

,那如何解决呢:使用volatile! 具体来说 就是使用了volatile 就会将CPU的高级缓存给写入主内存中 读取的时候也是从主内存中来读取的,这样一来就能保证内存的可见性。底层是基于系统

的内存屏障实现的,因为使用了内存屏障,所以就会禁止指令重排,保证了有序性。

总结:

使用volatile可以解决内存可见性问题和防止指令重排,而单例模式使用volatile主要是用volatile后一个特性(防止指令重排),从而避免在多线程使用的情况下,由于某个线程读取到一个未完全

实例化的对象,而导致程序出错!

标签:要加,SingleTonDemo02,模式,volatile,内存,单例,懒汉
From: https://www.cnblogs.com/bichen-01/p/17091044.html

相关文章

  • 单例模式
    单例模式这边主要写单例模式的实现方式和总结:话不多说直接上代码:单例模式之饿汉模式:代码(Coding):/***饿汉模式:在类加载的时候就把对象给一并加载完成因此不存在线程......
  • 设计模式(三)----创建型模式之单例模式(一)
    一、创建型模式创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建......
  • C++ Day11 使用单例模式封装log4cpp
    一、实现log4cpp的封装,使其可以像printf一样使用,测试用例如下: 思路:使用可变模板参数,最终达到的效果是在使用 LogInfo、LogError、LogWarn、LogDebug时候可以传递任意类......
  • 单例模式声明和使用
    1.#ifndef__INFRAY_SINGLETON_H__#define__INFRAY_SINGLETON_H__#include<unistd.h>#definePATTERN_SINGLETON_DECLAREY(classname)\private:......
  • 【python学习随笔】02 python的简单例子
    02python的简单例子fromrandomimportrandrange,shuffledefbubbleSort():array=[]whilelen(array)<12:#范围内随机取12个数值array.a......
  • 笔记:单例模式---懒汉模式和饿汉模式
    饿汉模式:用人吃东西来比喻的话,就是小花害怕饿,她把东西都准备好了,到时候饿了就可以直接吃。总结:我先new好,如果后面需要,拿这个用就好了。代码实现:publicclassSingle{......
  • volatile和synchronized关键字
    1.volatile关键字 Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这......
  • 24种设计模式之单例模式(singleton)
    24种设计模式之单例模式(singleton)目录24种设计模式之单例模式(singleton)饿汉模式:推荐使用懒汉模式:不推荐静态内部类模式:推荐最完美的方式java之父推荐:解决线程同步、反序......
  • C++ 单例模式最佳实践
    单例模式有很多种实现:懒汉/饿汉非线程安全线程安全每次判空加锁(效率不高)DCL:Double-checklock(繁琐,C++11之前的最佳实现)Meyers’singleton:静态变量(简洁,C++11之后......
  • 单例模式之延迟加载和初始加载
    一、什么是初始加载?实现单例模式有两种方式,一种是懒加载,也就是延迟加载,当首次调用时创建单例对象,另一种是初始加载,在应用程序启动时就初始化单例对象,并将其保存在内存中以......