精华内容
下载资源
问答
  • * @description 双重检验锁单例模式 */ public class Main { public static void main(String[] args) { Singleton a = Singleton.getInstance(); Singleton b = Singleton.getInstance(); System.o

    代码:

    /**
     * @author 士多啤梨西多士
     * @date 2020/9/9 23:51
     * @description 双重检验锁单例模式
     */
    public class Main {
        public static void main(String[] args) {
            Singleton a = Singleton.getInstance();
            Singleton b = Singleton.getInstance();
            System.out.println(a);
            System.out.println(b);
            System.out.println(a == b);
        }
    }
    
    class Singleton {
        private static volatile Singleton instance;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if(instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null){
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
    展开全文
  • 多线程下,减少进入synchronized的等待队列的请求,提高效率。例如,已经创建了单例,线程T1进入,判断instance不为空,就不用进入同步代码块。 3、第二个if(instance null)的作用 防止生成多个实例。比如,...
    class Singleton{
    	private static volatile Singleton instance=null;
    	private Singleton() {}
    	public static Singleton getInstance() {
    		if (instance==null) {
    			synchronized(Singleton.class) {
    				if (instance==null) {
    					instance=new Singleton();
    				}
    			}
    		}
    		return instance;
    	}
    }
    

    1、volatile的作用
    在instance=new Singleton();中,这段代码是分3步执行的
    (1)为instance分配内存空间
    (2)初始化instance
    (3)将instance指向分配的内存地址
    由于jvm具有指令重排序的特性,执行的顺序可能变成1->3->2,所以在多线程环境下,可能一个线程会得到还没有初始化的实例。比如,线程T1执行了1、3,线程T2来发现instance不为空,所以返回instance,但是instance还没有初始化,所以需要volatile禁止指令重排序。
    2、第一个if(instancenull)的作用
    多线程下,减少进入synchronized锁的等待队列的请求,提高效率。例如,已经创建了单例,线程T1进入,判断instance不为空,就不用进入同步代码块。
    3、第二个if(instance
    null)的作用
    防止生成多个实例。比如,线程T1还没有将instance指向分配的内存空间,线程T2在synchronized的等待队列中等待,当T1完成单例创建,然后如果没有if判断,T2也会生成单例实例,所以需要第二个if判断。

    展开全文
  • 由于普通写法的懒汉式单例模式在多线程情况下是不安全的,所以出现了安全的懒汉式单例模式的写法,即双重检验锁模式。 class Singleton{ // 确保产生的对象完整性 private volatile static Singleton ...

    volatile关键字的特性

      1、保证被volatile定义的变量对所有线程的可见性

    •         即某线程对volatile变量的操作,其他线程会立刻得知

      2、使用volatile变量的语义是禁止指令重排序

    •        volatile变量前面的操作结果对于后面的操作可见的。

    •        volatile变量前面的代码一定会先于后面的代码执行。

    由于普通写法的懒汉式单例模式在多线程情况下是不安全的,所以出现了安全的懒汉式单例模式的写法,即双重检验锁模式。

    class Singleton{
        // 确保产生的对象完整性
        private volatile static Singleton instance = null;
        private Singleton() {}
        public static Singleton getInstance() {
            if(instance==null) { // 第一次检查
                synchronized (Singleton.class) {
                    if(instance==null) // 第二次检查
                        instance = new Singleton();
                }
            }
            return instance;
        }
    }

    双重检验锁的原因:

      1、第一次检查,目的是检查当前对象是否已经被初始化。

      2、第二次检查,是防止对象被初始化多次。

            假设线程A在完成对象的初始化后,释放锁,在返回此对象之前,线程B获得锁,然后再次进行初始化操作。这样会导致生成多个对象实例。

      3、使用volatile关键字,是为了保证对象被初始化完成后,才被返回。

            因为 instance = new Singleton();不是原子性操作。假设线程A还尚未将对象的属性初始化完毕,而线程B在第一次检查时,就发现当前对象不为空,然后返回该对象。这样就会破坏对象的完整性。

    展开全文
  • 双重校验实现对象单例(线程安全) public class Singleton { private volatile static Singleton singleton; private Singleton() {} public static Singleton getInstance() { if (singleton == null) { ...

    双重校验锁实现对象单例(线程安全)

    public class Singleton {
    
        private volatile static Singleton singleton;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if (singleton == null) {
                // 类对象加锁
                synchronized (Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
    

    singleton 采用 volatile 关键字修饰是很有必要的。

    singleton = new Singleton(); 这段代码其实是分为三步执行:

    1. singleton 分配内存空间
    2. 初始化 singleton
    3. singleton 指向分配的内存地址

    但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1–> 3 --> 2。指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。

    例如,线程 T1 执行了 1 和 3,此时 T2 调用 getInstance() 后发现 singleton 不为空,因此返回 singleton ,但此时 singleton 还未被初始化。

    使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行。

    展开全文
  • 在网上看到过好多篇文章在说明双重检查在多个线程初始化一个单例类时到底为什么不行时在关键位置的描述模棱两可,今天我们就来看一下为什么不能用双重检查,问题到底出在了那里? 下面我们直接进入主题...
  • public class Singleton { private ...但是由于Java编译器允许处理器乱序执行,以及JDK5之前JVM中Cache、寄存器到主...如果已经初始化,则不必再争夺。 第二个判断是否为null,保证只有一个实例被初始化。
  • 虽然这篇文章中也分析了如何利用同步锁机制保证懒汉式单例模式的线程安全问题,同步方法,同步代码块等,但都非最优的解决方法,今天我们就来讲讲什么是双重检验锁方式实现单例模式,包括它的特点和原理。...
  • 单例模式(懒汉方式和饿汉方式)+双重检验锁单例模式的概念:单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 1)一个类只有一个...
  • maven需要的依赖 <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>...depen...
  • 懒汉单例模式 优化DCL设计模式 也就是双重检验锁模式 / * description: 单例DCL设计模式 也就是双重检验锁模式 */ public class Dclsingleton { private static volatile Dclsingleton instance = null; ...
  • 单例模式双重检验锁

    千次阅读 2018-03-23 11:00:24
    当被问到要实现一个单例模式时,很多人的第一反应是写出如下的代码,包括教科书上也是这样教我们的。 public class Singleton { private static Singleton instance; private Singleton (){} public static ...
  • 单例模式双重检验锁的判断是否为null的意义
  • 双重检验锁⽅式实现单例模式的原理 实例目的:保证线程安全 学习代码: public class Singleton { private volatile static Singleton uniqueInstance; private Singleton() { } public static Singleton ...
  • * 单例模式-双重校验 * @author szekinwin * */ public class SingleTon3 { private SingleTon3(){}; //私有化构造方法 private static volatile SingleTon3 singleTon=null; public static SingleTon3 ...
  • 单例模式为什么加双重检验锁一、代码?二、为什么双重校验为什么需要两次判断if(uniqueSingle==null)?volatile关键字 一、代码? 代码: public class Singleton { private static volatile Singleton ...
  • 在我前面有写过一篇关于单例模式的几种创建的文章,最近在看多线程的时候,发现如果使用双重检验锁则可能会发生问题,接下来看我细细道来 单例模式的几种创建方式文章地址:https://www.jianshu.com/p/8ec72e016275 首先...
  • 1:单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳...2:单例模式的实现有很多种本文着重讨论双重校验 首先写如下代码: package ...
  • 之前我们使用单例模式经常会用到两种方式,一种是懒汉是双重锁,一种是静态内部类,可以看下这个深入理解单例模式:静态内部类单例原理,但是其中用到的双重锁懒汉模式 其实并非是真正的线程安全的。 例如这样: ...
  • 网上很多人说,使用双重检验锁方法实现单例模式可能会new多个实例,而内部类方法和枚举类方法完美解决了这个问题 因为Android很少使用枚举,本次只研究双重检验锁方法和内部类方法 双重检验锁方法: 代码如下: ...
  • 单例模式之DCL懒汉式解析(双重检验锁) 双重检验锁不安全的原因 在下面的代码进行到: lazyMan = new LazyMan();的时候有可能会进行指令重排. lazyMan = new LazyMan(); 这一句代码其实有3个操作 分配内存空间 执行...
  • 双重检验锁模式(double checked locking pattern),是一种使用同步块加锁的方法。程序员称其为双重检查,锁,因为会有两次检查 instance == null,一次是在同步块外,一次是在同步块内。为什么在同步块内还要再...
  • 单例模式详解(懒汉式、饿汉式、线程安全、双重检验锁) 单例(Singleton)概述 使单例模式是为了:保证一个类只有一个实例,并且提供这个实例的全局访问点 一般做法是把该单例实例作为该类的一个静态变量、构造方法...
  • 1. 双重检验锁该部分内容引自维基百科。package com.fqyuan.con_singleton;public class SingletonClass { private static volatile SingletonClass INSTANCE; //private constructor. private SingletonClass() {...
  • 上面是一个单例模式双重检查的实现。 上述的重点是: 1. 使用了volatile关键字。 2. 两次判断 instance==null 3. 对类加锁 先看第一个,使用volatile关键字。 如果没有使用volatile这一关键字会出现什么情况呢。 ...
  • 最简单的单例模式举例实现方式饿汉式单例模式懒汉式单例模式线程同步改进饿汉式单例模式(DCL双重检验锁)禁止指令重排改进饿汉式单例模式 本文是根据作者自己的学习思路梳理单例模式的知识点 什么是单例模式? ...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 184
精华内容 73
关键字:

双重检验锁单例模式