美文网首页
单例模式(懒汉模式)

单例模式(懒汉模式)

作者: dependmyse | 来源:发表于2016-08-23 17:39 被阅读0次
package com.exam.test;

/**
 * 懒汉式单例
 * Created by xiangyang.laixiang on 2016/8/23.
 */
public class SingleInstance {
    private static SingleInstance singleInstance;

    /**
     * 懒汉式单例,非线程安全
     * @return
     */
    public static SingleInstance getSingleInstance(){
        if(singleInstance == null)
        {
            singleInstance = new  SingleInstance();
        }
        return singleInstance;
    }

    /**
     * 懒汉式单例,线程安全
     * 这是实现线程安全最简单的方式,但这里会导致一个性能问题,因为我们把整个getInstance同步起来了,
     * 这就会导致每时每刻都只能有一个线程调用getInstance方法,而同步只发生在第一次声明的时候
     * 这就引出了双重检验锁的概念
     * @return
     */
    public synchronized static SingleInstance getSingleInstance2(){
        if(singleInstance == null)
        {
            singleInstance = new  SingleInstance();
        }
        return singleInstance;
    }
}


/**
 * 双重检验锁
 */
class DoubleCheckSingleInstance{
    //使用volatile关键字修饰
    //private static DoubleCheckSingleInstance singleInstance;
    private static DoubleCheckSingleInstance singleInstance;
    public static DoubleCheckSingleInstance getSingleInstance()
    {
        if(singleInstance == null)
        {
            synchronized (DoubleCheckSingleInstance.class)
            {
                if(singleInstance == null)
                {
                    singleInstance = new DoubleCheckSingleInstance();
                }
            }
        }
        return singleInstance;
    }

    /**
     * 上述这段代码看起来很完美,但是中间存在着一个问题那就是 new DoubleCheckSingleInstance()
     * 这个操作不是原子操作,大致有三步构成。
     * 1. 给instance分配内存
     * 2. 调用DoubleCheckSingleInstance构造函数初始化成员变量
     * 3. 将instance指向内存
     * 问题就出在这一部分,jvm即时编译器中存在着指令重排序的优化。如果1,2,3的执行步骤不会存在问题
     * 倘若1,3,2
     * 那么当线程二执行完第三步以后,线程三抢占cpu资源,则进行检查,发现instance不为空,则返回,但此时
     * 成员变量尚未初始化,则会发生调用错误。
     * 解决方案是使用volatile来修饰singleInstance来强制每次都从内存映像中读取数据,其实volitile也可以起到
     * 禁止重排序的功能,在java1.5以后使用比较安全。(1.5之前的内存模型是存在问题的)
     */
}

/**
 * effective java中推荐的内部类实现单例的写法 。
 */
class SingtonInstance{
    private SingtonInstance()
    {
        System.out.println("constructor");
    }
    private static class SingtonHolder{
        private static SingtonInstance instance = new SingtonInstance();
    }
    public static void beforeInvoke()
    {
        System.out.println("before invoke");
    }

    public static SingtonInstance getInstance()
    {
        /**
         * 此处最开始理解有点绕,但是经过我对象的一个提醒恍然明白,对于内部类的所有对象对于其
         * 外部类来说都是可见的,简直是霸气,否则private的可见范围是不允许直接访问的。
         */
        return SingtonHolder.instance;
    }
}

public class Test {
    public static void main(String[] args) {
        SingtonInstance.beforeInvoke();
        SingtonInstance.getInstance().beforeInvoke();
    }
}

相关文章

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • java的单例模式

    饿汉单例模式 懒汉单例模式

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • kotlin实现单例模式

    1.懒汉式实现单例模式 2.线程安全懒汉式实现单例模式 3.双重校验懒汉式实现单例模式 4.静态内部类方式实现单例模式

  • Java单例模式

    1. 实现单例模式 饿汉模式和懒汉模式单例模式根据实例化时机分为饿汉模式和懒汉模式。饿汉模式,是指不等到单例真正使...

  • Singleton 单例模式

    饿汉式单例模式 饿汉式单例模式 通过静态代码块增加异常处理 懒汉式单例模式 存在线程安全问题 懒汉式单例模式 解决...

  • 设计模式

    一、单例模式 饿汉模式 懒汉模式

  • Java23种设计模式之「单例模式」

    单例模式 之 holder 模式 (推荐) 单例模式 之 饱汉模式(懒汉模式) 单例模式 之 双重锁检查 (Dou...

  • 单例模式有几种写法?

    懒汉模式 懒汉是变种最多的单例模式。我们从懒汉出发,通过其变种逐渐了解实现单例模式时需要关注的问题。 基础的懒汉 ...

网友评论

      本文标题:单例模式(懒汉模式)

      本文链接:https://www.haomeiwen.com/subject/adrnsttx.html