设计模式之单例模式

Posted jiangtunan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之单例模式相关的知识,希望对你有一定的参考价值。

 

今天我们来介绍一下设计模式中比较常见的单例模式,希望读完本文你可以对单例模式有一个比较全面的认识。

什么是单例模式?

单例模式就是需要保证一个类仅有一个实例,并提供一个访问它的全局访问点。

为什么要使用单例模式?

对于一些类来说,只有一个实例是很重要的。比如说一个班级里面可以有很多学生但是通常只有一个班主任。如果说我们 new 出若干个班主任就可能会出现一些逻辑上的问题。

单例模式的实现

通常在Java中单例模式有两种创建方式

  • 饿汉方式:指全局的单例实例在类装载时构建

  • 懒汉方式:指全局的单例实例在第一次被使用时构建。

不管是那种创建方式,它们通常都存在下面几点相似处:

单例类必须要有一个 private 访问级别的构造函数,只有这样,才能确保单例不会在系统中的其他代码内被实例化.

首先我们来看一看饿汉模式

package com.it.nowcoder;

public class Singleton 

    private static Singleton uniqueInstance = new Singleton();
    //在静态初始化器中创建实例,线程安全
    private Singleton() 
    
    //将构造函数设为私有,外界无法调用。不能通过new来调用构造函数。
    public static Singleton getInstance() 
        return uniqueInstance;
    
    //供外界调用的方法

 

所谓 “饿汉方式” 就是说JVM在加载这个类时就马上创建此唯一的单例实例,不管你用不用,先创建了再说,如果一直没有被使用,便浪费了空间,典型的空间换时间,每次调用的时候,就不需要再判断,节省了运行时间。

此种方法比较常用,因为没有加锁所以执行效率比较高。但是在类加载时就会进行初始化所以会浪费部分内存。

懒汉模式(非线程安全)

 

package com.it.nowcoder;

public class Singleton 

    private static Singleton uniqueInstance;

    private Singleton() 
    
    
    public static Singleton getInstance() 
        if (uniqueInstance == null) 
            uniqueInstance = new Singleton();
        
        return uniqueInstance;
    

 

所谓 “ 懒汉式” 就是说单例实例在第一次被使用时构建,而不是在JVM在加载这个类时就马上创建此唯一的单例实例。在这种情况下多个线程同时调用getInstance就会发生线程安全问题。

懒汉模式(Synchronzied版本)

 

public class Singleton 

    private static Singleton uniqueInstance;

    private Singleton() 
    

    public static synchronized Singleton getInstance() 
        if (uniqueInstance == null) 
            uniqueInstance = new Singleton();
        
        return uniqueInstance;
    

这种方式下我们每次调用getInstance都会经过Synchronzied关键字,会造成一些资源的消耗。

 

 

懒汉模式(双重检查加锁版本)

利用双重检查加锁(double-checked locking),首先检查是否实例已经创建,如果尚未创建,“才”进行同步。这样以来,只有一次同步,这正是我们想要的效果。

 

 

 

public class Singleton 

    //volatile保证,当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确处理uniqueInstance变量
    private volatile static Singleton uniqueInstance;

    private Singleton() 
    

    public static Singleton getInstance() 
        //检查实例,如果不存在,就进入同步代码块
        if (uniqueInstance == null) 
            //只有第一次才彻底执行这里的代码
            synchronized (Singleton.class) 
                //进入同步代码块后,再检查一次,如果仍是null,才创建实例
                if (uniqueInstance == null) 
                    uniqueInstance = new Singleton();
                
            
        
        return uniqueInstance;
    

 

本文中我们介绍了创建单例模式的几种方式,希望对你有所帮助。

 

以上是关于设计模式之单例模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之单例模式

JAVA设计模式之单例模式(转)

单例模式之单例模式

JAVA设计模式之单例模式

《JAVA与模式》之单例模式

《JAVA与模式》之单例模式