设计模式笔记 Singleton 单例模式

单例模式大概是最直观的一种设计模式了,尽管直观却不简单。

数学与逻辑学中,singleton定义为“有且仅有一个元素的集合”,

单例模式可以如下定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供”。

我比较喜欢Design Patterns 一书中的描述"保证一个类仅有一个实例,并提供一个访问它的全局访问点"。

单例模式的特点

1.单例类只能有一个实例

2.单例类必须自己自己创建自己的唯一实例

3.例类必须给所有其他对象提供这一实例

单例模式的经典实现

实现单例,可以将类的构造方法限定为private,避免在外部实例化,然后在类中提供一个静态的实例并能够返回给使用者,
在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance方法访问。

 


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public class Singleton {

 

/**

* classic singleton

* realize lazy loaded 添加判断uniqueInstance是否初始化,实现了使用时才进行加载

*/

private static Singleton uniqueInstance=null;

 

private Singleton(){

//Exits only to defeat instantiation

}

public static Singleton getInstance(){

if(uniqueInstance==null){

uniqueInstance =new Singleton();

}

return uniqueInstance;

}

}

 

线程安全的实现  

经典的实现方法并没有考虑多线程的环境,试想存在两个线程A和B,
同时调用getInstance方法,线程A检查uniqueInstance是null,开始创建实例;
同时线程B检测到uniqueInstance是null,于是线程A/B各自创建了对象。

解决这个问题最简单的方法是加锁,为getInstance的静态方法添加synchronized关键字,
但是考虑到Synchronized同步锁的性能较低,可以调整Synchronized添加(加锁)的位置。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

public class SingletonSafed {

 

    /**

     * 要在于instance = new Singleton()这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情。

     * 给 instance 分配内存

     * 调用 Singleton 的构造函数来初始化成员变量

     * 将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)

     * 使用volatile禁止指令重排序优化

     */

    //在Java里所有引用类型的静态以及实例成员,没有显式地初始化的,都会被设为null

    private volatile static SingletonSafed uniqueInstance;

     

    private SingletonSafed(){

        //私有的构造方法,防止外部实例化

    }

     

    //注意设置为静态方法

    public static SingletonSafed getInstance(){

        if(uniqueInstance== null){

            /**

             * 同步块加锁。双重检查锁,因为会有两次检查 instance == null,一次是在同步块外,一次是在同步块内。

             * 为什么在同步块内还要再检验一次?因为可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例。

             */

            synchronized(SingletonSafed.class){

                if(uniqueInstance== null){

                    uniqueInstance= new SingletonSafed();                  

                }

                 

            }

        }

            return uniqueInstance;

    }

}

  

饿汉式 懒汉式和登记式

另外,一些文档会提到单例模式的三种形式(懒汉式,饿汉式,登记式),
其实饿汉式和懒汉式主要是线程安全的区别,同时懒汉式是延迟加载,
在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建,例如下面代码:


1

2

3

4

5

6

7

8

9

10

11

//饿汉式单例类.在类初始化时,已经自行实例化

public class Singleton1 {

//私有的默认构造子

private Singleton1() {}

//已经自行实例化

private static final Singleton1 single = new Singleton1();

//静态工厂方法

public static Singleton1 getInstance() {

return single;

}

}

懒汉式单例:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

//懒汉式单例类.在第一次调用的时候实例化

public class Singleton2 {

//私有的默认构造子

private Singleton2() {}

//注意,这里没有final

private static Singleton2 single=null;

//静态工厂方法

public synchronized static Singleton2 getInstance() {

if (single == null) {

single = new Singleton2();

}

return single;

}

}

 

时间: 2024-11-03 17:19:31

设计模式笔记 Singleton 单例模式的相关文章

深入解析Java的设计模式编程中单例模式的使用_java

定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 类型:创建类模式 类图: 类图知识点: 1.类图分为三部分,依次是类名.属性.方法 2.以<<开头和以>>结尾的为注释信息 3.修饰符+代表public,-代表private,#代表protected,什么都没有代表包可见. 4.带下划线的属性或方法代表是静态的. 5.对类图中对象的关系不熟悉的朋友可以参考文章:设计模式中类的关系. 单例模式应该是23种设计模式中最简单的一种模式了.它有以下几个要素: 私有的构

Android设计模式系列之单例模式

单例模式,可以说是GOF的23种设计模式中最简单的一个. 这个模式相对于其他几个模式比较独立,它只负责控制自己的实例化数量单一(而不是考虑为用户产生什么样的实例),很有意思,是一个感觉上很干净的模式,本人很喜欢这个模式. android中很多地方都用到了单例模式,本文以输入法管理者InputMethodManager为例,展开分析. 单例模式,Singleton Pattern,能够以其特有的优势,替代系统中全局变量,应用非常广泛. 1.意图 保证一个类仅有一个实例,并提供一个访问它的全局访问点

设计模式之Singleton

设计 设计模式之SingletonSingleton定义:Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作. 还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口

php实现singleton()单例模式实例_php技巧

本文实例讲述了php实现singleton()单例模式的方法.分享给大家供大家参考.具体实现方法如下: common.php文件如下: 复制代码 代码如下: <?php  class CC  {  private static $ins;  public static function singleton()   {           if (!isset(self::$ins)){              $c = __CLASS__;              self::$ins =

我的设计模式学习笔记------&amp;gt;单例模式(Singleton)

一.前言 有些时候,允许自由创建某个类的实例是没有意义,还可能造成系统性能下降(因为创建对象所带来的系统开销问题).例如整个Windows系统只有一个窗口管理器,只有一个回收站等.在Java EE应用中可能只需要一个数据库引擎访问点,Hibernate访问时只需要一个SessionFactory实例,如果在系统中为它们创建多个实例就没有太大的意义. 如果一个类始终只能创建一个实例,则这个类被称为单例类,这种模式就被称为单例模式. 对Spring框架而言,可以在配置Bean实例时指定scope="

《设计模式》学习笔记5——单例模式【高并发拓展】

定义 单例模式又称为单件模式,这个模式大概是设计模式中最好理解的了,我起初就打算从这里开始学,甚至还记过另一篇单例模式学习的笔记. 但是之后跟着<设计模式>这本书系统的学,就索性从第一页开始,而单例模式算是复习,也算是再深入的理解一次. 之所以要这么做,是因为上一次写的没有给出更标准的定义,同时,当时只介绍了基础的懒汉式和饿汉式,对于并发时候的单例却没有涉及,所以这篇学习的重点应当在于高并发时如何保证我们的单例依旧是单例. 单例模式引用书中的定义如下: 单例模式(Singleton Patte

使用设计模式中的Singleton单例模式来开发iOS应用程序_IOS

单例设计模式确切的说就是一个类只有一个实例,有一个全局的接口来访问这个实例.当第一次载入的时候,它通常使用延时加载的方法创建单一实例. 提示:苹果大量的使用了这种方法.例子:[NSUserDefaults standerUserDefaults], [UIApplication sharedApplication], [UIScreen mainScreen], [NSFileManager defaultManager] 都返回一个单一对象. 你可能想知道你为什么要关心一个类有多个的实例.代码

php设计模式 Singleton(单例模式)

复制代码 代码如下: <?php /** * 单例模式 * * 保证一个类仅有一个实例,并提供一个访问它的全局访问点 * */ class Singleton { static private $_instance = null; private function __construct() { } static public function getInstance() { if(is_null(self::$_instance)) { self::$_instance = new Singl

.Net设计模式实例之单例模式( Singleton Pattern)

一.单例模式简介(Brief Introduction) 单例模式(Singleton Pattern),保证一个类只有一个实例,并提供一个访问它的全局访问点.单例模式因为Singleton封装它的唯一实例,它就可以严格地控制客户怎样访问它以及何时访问它. 二.解决的问题(What To Solve) 当一个类只允许创建一个实例时,可以考虑使用单例模式. 三.单例模式分析(Analysis)1.单例模式结构 Singleton类,定义一个私有变量instance;私有构造方法Singleton(