线程安全的单例模式的常用四种创建方式

标签: 单例模式 线程安全
5人阅读 评论(0) 收藏 举报
分类:

单例模式是常用的一种设计模式,线程安全的单例模式一般有三种写法,其中双重检查模式是最复杂的,也是不推荐的。
那有没有更好的推荐方式呢?答案是肯定的。请继续往下看。

1. 不使用同步锁

饱汉式

public class Singleton {

    //直接初始化
    private static Singleton instance = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

优点:这种方式的性能是非常好的,只是简单返回instance,没有做其他任何锁操作,所以在并行程序中,会有良好表现。
缺点:但是有点明显的不足之处是 Singleton 实例在何时被创建并不受控制,对于静态成员变量instance,会在类第一次初始化的时候被创建,但是这并不一定是getInstance() 方法第一次调用的时候。

2. 使用同步锁

懒汉式

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

优点:充分利用了延迟加载,只在真正需要的时候创建对象。(只在第一次调用时创建对象)
缺点:为了防止对象被多次创建,不得不使用synchronized进行方法同步。并发环境下,竞争激烈的场合对性能可能产生一定的影响。

3. 双重检查模式

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if(instance == null) {
            synchronized(Singleton.class) {
                if(instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

优点:这种方式在第二种的基础上做了改进,调用 getInstance() 方法的时候不需要每次都锁类对象。如果 instance 实例已经创建,则直接返回。
缺点:在JDK1.5之后才能保证正确性,比较丑陋复杂,这里不推荐,推荐如下第四种方式。

4. 利用虚拟机的类初始化机制

这里介绍下推荐使用的一种,这种方式结合了第一种不需要同步锁和第二种延迟加载的优点。

public class Singleton {

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
    //内部静态私有化类
    private static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }
}

这种方式没有锁,在高并发环境下性能更好;延迟加载,只在第一次调用时被创建。
这种方式巧妙地利用了内部类和类的初始化方式,内部类被申明为 private ,这使得我们不可能在外部访问并初始化它。只可能在 getInstance() 方法内部对 SingletonHolder 类进行初始化。

查看评论

实现类似Windows资源管理器的DataGrid

在DataGrid中,我们可以实现类似Windows资源管理器的效果,即对列进行排序,该列颜色与其它列不同。下面就是实现的代码:DataGridLikeWindowsExplorer.aspx@ Pa...
  • net_lover
  • net_lover
  • 2003-11-04 01:30:00
  • 3430

Singleton单例模式的几种创建方法

创建单例类有以下几种方式: 饿汉式 懒汉式(加同步锁的懒汉式、加双重校验锁的懒汉式、防止指令重排优化的懒汉式) 登记式单例模式 静态内部类单例模式 枚举类型的单例模式 备注: 其中“枚举类型的单例...
  • hl_java
  • hl_java
  • 2017-04-12 22:53:47
  • 485

如何创建线程安全的单例模式?线程安全的Singleton!

单例模式的概念 单例模式就是确保只有一个实例,而且自行实例化并向整个系统传递这个实例,这个类就称作为单例类 单例模式最重要的一个特点就是构造方法私有化。创建单例模式分为懒汉式和饿汉式。 ...
  • a347911
  • a347911
  • 2016-11-24 16:59:35
  • 2006

设计模式——单例模式(Java)——考虑多线程环境下的线程安全问题

设计模式——单例模式(Java)——考虑多线程环境下的线程安全问题 一:单例模式概念 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类...
  • ly969434341
  • ly969434341
  • 2016-05-10 21:38:42
  • 2814

单例模式中采用的延迟加载创建单例(内部类)

此篇文章为看别人的文章自己小小记录的一点日常知识。 在创建单例模式的时候,如果单纯的只考虑单例而不思考那样做的话会产生什么问题这样是不严谨的,比如会发生线程安全问题,看了一些文章其中一篇写得非常详细有...
  • qq_27409289
  • qq_27409289
  • 2016-07-06 13:58:45
  • 450

线程安全的单例模式

  • 2012年12月07日 15:29
  • 345KB
  • 下载

创建单例模式(Singleton)的几种方式

单例模式可能是最常用到的设计模式了,但是想要正确的使用单例模式却并不简单。 我们先从最简单最常用的方式开始: 懒汉式 public class Singleton { private...
  • z719725611
  • z719725611
  • 2016-09-29 21:36:33
  • 231

单例模式的七种写法, 面试题:线程安全的单例模式

http://cantellow.iteye.com/blog/838473 http://meizhi.iteye.com/blog/537563 转载请注明出处:h...
  • liangxw1
  • liangxw1
  • 2016-05-09 15:53:18
  • 11234

单例模式——C++实现线程安全的单例

一、懒汉模式:即第一次调用该类实例的时候才产生一个新的该类实例,并在以后仅返回此实例。 需要用锁,来保证其线程安全性:原因:多个线程可能进入判断是否已经存在实例的if语句,从而non thread ...
  • fu_zk
  • fu_zk
  • 2013-09-22 11:04:05
  • 21474

ios中的线程安全单例实现

我们这里重点讨论的是线程安全,而不是单例的严格实现(若需要严格实现还需要复写一些方法,更改一些实现代码): gcd实现:   static AccountManager *sharedAcco...
  • openglnewbee
  • openglnewbee
  • 2013-11-18 10:54:44
  • 5740
    个人资料
    等级:
    访问量: 331
    积分: 35
    排名: 156万+
    文章分类
    文章存档