码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之单例模式

时间:2019-07-06 17:40:27      阅读:89      评论:0      收藏:0      [点我收藏+]

标签:sync   locking   turn   线程安全   不用   访问级别   比较   问题   加锁   

 

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

什么是单例模式?

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

为什么要使用单例模式?

对于一些类来说,只有一个实例是很重要的。比如说一个班级里面可以有很多学生但是通常只有一个班主任。如果说我们 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;
    }
}

 

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

 

设计模式之单例模式

标签:sync   locking   turn   线程安全   不用   访问级别   比较   问题   加锁   

原文地址:https://www.cnblogs.com/jiangtunan/p/11143272.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!