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

双重校验锁实现单例模式:

public class Singleton {

    //采用volatile修饰
    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指令重排,从而保证在多线程下也能正常执行

原文地址:https://blog.51cto.com/13003060/2379049

时间: 2024-11-06 14:09:15

双重校验锁实现单例模式(对象单例,线程安全)的相关文章

双重检查锁实现单例模式的线程安全问题

一.结论 双重校验锁的单例模式代码如下: public class Singleton { private static Singleton singleton; private Singleton() {} public static Singleton getSingleton() { if (singleton == null) { // 1 synchronized (Singleton.class) { // 2 if (singleton == null) { // 3 single

单例模式 俗称单例3步曲+1曲

什么是单例模式?    在整个应用中通过这个类只能实例化一个对象实例的设计模式 模式分类? 在所有模式设计中,有三种基础设计模式,单例模式,工厂模式,注册树模式,其他模式往往基于这几种模式,今天带来的是单例模式. 为什么要用单例模式?    1.php常常和数据库打交道,如果在应用中频繁建立连接对象,进行new操作的话,会消耗大量的系统内存资源.(节省资源开销)    2.在团队合作项目中,单例模式可以有效避免不同程序员new自己的对象时,造成人为的系统消耗.(节省资源开销)  --------

C++单例模式与单例类模板

1.单例模式 (1)需求的提出:在架构设计时,某些类在整个系统生命周期中最多只能有一个对象存在(Single,Instance) (2)问题:如何定义一个类,使得这个类最多只能创建一个对象? 要控制类的对象数目,必须对外隐藏构造函数 思路: @1:将构造函数的访问属性设置为private,将拷贝构造函数,赋值操作符都声明成private的,防止对象的赋值操作,因为这个类的对象只能有一个. @2:定义instance并初始化为NULL.在类中用static type* instance的方式声明一

apply 伴生对象 单例对象

apply(): 当类或者对象有一个主要用途时,apply方法提供了很好语法机制 scala> class Foo {} defined class Foo scala> object FooMaker { | def apply() = new Foo | } defined module FooMaker scala> val newFoo = FooMaker() newFoo: Foo = [email protected] 写在object中时,使用方法:类名() 或者 sca

单例 --- 线程模式

1.Grand Central Dispatch --- GCD单次执行 --- 程序执行期间之执行一次 - (IBAction)GCD_onceDidClicked:(UIButton *)sender { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // code }); } 2.在单例中的应用 --- 此方法正吻合单例的特性(只执行一次,只alloc一次) + (instancetype)shareMusic

Scala学习 day01 Scala的类/方法/对象/单例对象

从今天开始,我将尽自己最大努力系统地学习Scala这门语言,希望自己能够坚持下去. Scala中的类 定义规则 class ClassName{     //类中的成员 } 在类定义里,可以放置字段和方法,这些被笼统地称之为成员

Android单例线程池

package com.jredu.schooltong.manager; import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors; public class ExecutorManager { // 1.私有构造函数,提供静态变量用以存储,提供静态的方法 private ExecutorManager() { init(); } // 静态变量 private static Execut

单例陷阱——双重检查锁中的指令重排问题

之前我曾经写过一篇文章<单例模式有8种写法,你知道么?>,其中提到了一种实现单例的方法-双重检查锁,最近在读并发方面的书籍,发现双重检查锁使用不当也并非绝对安全,在这里分享一下. 单例回顾 首先我们回顾一下最简单的单例模式是怎样的? /** *单例模式一:懒汉式(线程安全) */ public class Singleton1 { private static Singleton1 singleton1; private Singleton1() { } public static Singl

【设计模式(三)】单例模式——单例有几种写法?

有一回对我说道,“你写过编程么?”我略略点一点头.他说,“写过,……我便考你一考.单例模式,是怎样写的?”我想,讨饭一样的人,也配考我么?便回过脸去,不再理会.孔乙己等了许久,很恳切的说道,“不能写罢?……我教给你,记着! 单例模式(Singleton Pattern) 单例模式是 Java 中最简单的设计模式之一.这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建.这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象. 单例模式三要素:1.单