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

单例模式

时间:2018-07-31 00:32:34      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:模式   实现   引用   方法   不为   volatil   时间   tin   vat   

目录

前言

在特定场景下,我们需要在全局使用某一个对象的同一个实例,我们就需要保证一个对象不能存在多个实例。单例模式是一种很常见的设计模式;比如Servlet在Tomcat中是单例的,Spring IOC容器管理的Bean默认是单例的;单例模式就是为了保证一个对象对外只提供一个实例;单例模式实现方式比较多。

破坏单例

存在以下几种破坏单例的情况:

1.关键字new通过构造方法 2.多线程环境 3.反序列化 4.复制(clone) 5.反射

在实际应用中,实现单例模式时通常只需要考虑 1和2 两种情况;

实现单例模式

根据实例化的时间不同可分为两大类:

一是饿汉模式,这种方式在类加载阶段完成实例化;

二是懒汉模式,这种方式在使用的时候才去实例化。

单例模式的懒汉写法:

/**
 * 单例模式——懒汉
 * 双重校验
 */
class Singleton01 {
    /**
     * 使用volatile修饰的原因(禁止指令重排)
     * 指令重排有可能导致先将未初始化的对象的引用赋值给instance变量,再进行初始化
     * 也就是说可能出现一个线程还未对对象进行初始化,另外一个线程由于判断instance不为空于是获得了一个未初始化的对象
     */
    private static volatile Singleton01 instance = null;
    /**
     * 私有化构造函数
     */
    private Singleton01(){
        System.out.println("我被实例化了");
    }
    public static  Singleton01 getInstance(){
        //如果还未实例化,则进行同步(因为实际上实例化成功之后就不需要进行同步操作了)
        if(null == instance){
            synchronized(Singleton01.class){
                //最外层的判断没有进行同步,是非线程安全的,这里再次进行判断
                if(null == instance){
                    instance = new Singleton01();
                }
            }
        }
        return instance;
    }

}

单例模式的饿汉写法:

/**
 * 单例模式-饿汉
 * 
 */

class Singleton02 {
    /**
     * 在类加载初始化阶段实例化
     * 在这个阶段由于虚拟机已经进行了同步,因此是线程安全的
     */
    private static Singleton02 instance = new Singleton02();
    /**
     * 私有化构造函数
     */
    private Singleton02(){
        System.out.println("我被实例化了");
    }
    public static Singleton02 getInstance(){
        return instance;
    }

单例模式

标签:模式   实现   引用   方法   不为   volatil   时间   tin   vat   

原文地址:https://www.cnblogs.com/fengwbetter/p/9393481.html

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