单例应该这么写

Java代码

public class DoubleCheckSingleton {  

    private volatile static DoubleCheckSingleton instance = null;  

    private DoubleCheckSingleton() {}  

    public static DoubleCheckSingleton getInstance() {
        //先检查实例是否存在,不存在则进入下面的同步块
        if (instance == null){
            //同步块,线程安全的创建实例
            synchronized (DoubleCheckSingleton.class) {
                //再次检查是否存在实例,如果不存在,才真正创建实例
                if (instance == null) {
                    instance = new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }  

}

Q1. instance为什么要声明为static?
A1. static方法只能访问static属性,因为非static属性是为实例而存在的,而调用static方法不需要实例存在,所以instance必须声明为static。
Q2. getInstance方法里可以不加同步吗?
A2. 不可以,必须加,因为很明显存在多线程问题
Q3. 两次判断instance==null是必要的吗?
A3. 是非常必要的,我们在很多框架如spring中也常看到这样的写法。因为同步是有性能降低代价的,所以同步前需判断null,这个不是必须,但很必要,同步块里的则是必须的判断了。
Q4. instance为何声明为volatile?
A4. 线程能够自动发现volatile变量的最新值,且instance的值只有非常确定的两种情况,即null和单实例,所以instance声明为volatile,才能以最新的值判断instance==null,这是必须的。关于volatile与内存模型的解释,请看http://wely.iteye.com/blog/2324588 , http://wely.iteye.com/blog/2228828
Q5. 在调用方法时才new instance,这叫什么模式?
A5. 懒汉模式,或可称为懒加载模式。

原文链接:[]

时间: 2024-07-30 21:55:08

单例应该这么写的相关文章

java-Java 单例线程安全问题

问题描述 Java 单例线程安全问题 public class A { public final static A INSTANCE = new A(); private A(){} }这个类是不是线程安全的呢?单例能这样写吗? 解决方案 这种写法是线程安全的.但是在该类一开始被加载的时候INSTANCE = new A()就会被执行.具体参考陈皓的博客深入浅出单实例Singleton设计模式介绍得非常详细. 解决方案二: 如果单线程中初始化,多线程中应用就没问题. 解决方案三: 深入解析单例线

如果重复使用单例的代码?

问题描述 我又一个需求interface Baseclass Base1 implements Baseclass Base2 ...class Base3如果Base1,2,3都是单例,我需要在每一个class里面都按照单例的写法写一次,有没有办法复用这样的代码?Thx 解决方案 interface Base class Base1 implements Base class Base2 extends Base1 class Base3 extends Base2让class Base2 .

PHP单例:只在整个页面周期内唯一

由于asp.net是编译型的,所以单例一直会存在于这个应用程序的生命周期里,真正可以做到这个实例在应用程序生命周期中的唯一性. 单例模式的存在在一些情况下是比较有意义的,如BlogEngine的站点配置就是采用的单例模式,而且它的载入和保存的代码是相当经典的,有兴趣可以看看它的源代码. 由于asp.net是编译型的,所以单例一直会存在于这个应用程序的生命周期里,真正可以做到这个实例在应用程序生命周期中的唯一性. php的单例模式的实现大致如下: class Stat{       static

Ruby设计模式透析:单例(Singleton)

写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你 分析数据,但是Ruby原生带有的puts方法却很少在真正的项目开发中使用. 为什么作为Ruby新 手神器的puts,到了真正项目开发当中会被唾弃呢?其实只要细细分析,你就会发现它的很多弊端.比 如不可控制,所有的日志都会在项目上线后照常打印,从而降低运行效率:又或者不能将日志记录到本 地文件,一旦打印被清除,日志将再也找不回来:再或者打印的内容没有Tag区分,你将很难辨别这一 行日志是在哪个类里打印的. 你的

PHP里的单例类写法实例

  这篇文章主要介绍了PHP里的单例类写法实例,本文直接给出代码实例,需要的朋友可以参考下 PHP里的单实例类在进行数据交换,节省内存上还是很有意义的.写个简单例子. 类1,单实例类本身: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class UTIL { private static $instance; public function get() { if (!self::$instance) { self::$instance = new UTIL(

iOS利用单例实现不同界面间的数据传输

  首先写一个单例类,继承NSObject check.h文件中 @property(strong ,nonatomic) UITable * Table; @property(strong ,nonitomic) UITextFiled * Text; +(check*)shareDataModle; check.m中 //定义一个静态的checke类的对象,并赋给一个空值 static check * dataModle = nil; +(check*)shareDataModle { if

asp.net中C++单例实现问题分析

  方案一  代码如下   class QMManager { public:     static QMManager &instance()     {         static QMManager instance_;         return instance_;     } } 这是最简单的版本,在单线程下(或者是C++0X下)是没任何问题的,但在多线程下就不行了,因为static QMManager instance_;这句话不是线程安全的. 在局部作用域下的静态变量在编译时

学会放下包袱,热爱单例

原文链接  译者:曾维朝 企业应用程序与移动应用程序有着截然不同的要求.你启动一次企业应用程序,它会连续运行数月或数年.另一方面,大部分手机应用可能是被正在无聊排队或者坐公交车的用户启动的,它们经常连续运行不超过几分钟,这就意味着移动应用程序必须即时开启,而启动一个企业应用程序则需要足够长的时间. 对于企业应用,依赖注入和早期验证是非常重要的, Spring为此提供了极大的便利. 但是别欺骗自己,Spring是好,但它不是万金油.尤其在崇尚快速启动.低内存消耗.避免接口的移动开发领域. 企业应用

浅谈Java编程中的单例设计模式_java

写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像findbugs等代码检查工具还会认为使用System.out.println()是一个bug. 为什么作为Java新手神器的System.out.println(),到了真正项目开发当中会被唾弃呢?其实只要细细分析,你就会发现它的很多弊端.比如不可控制,所有的日志都会在项目上线后照常打印,从而降低运