• java设计模式——单例模式


    1.饿汉式

     线程安全,不管用不用都会创建对象,拿空间换时间。

    /**
     * 饿汉式
     */
    public class Singleton {
        private static Singleton instance = new Singleton ();
    
        private Singleton () {}
    
        public static Singleton getInstance() {
            return instance;
        }
    }
    

     

    2.懒汉式

     进行一次非空判断,可能会出现一个或多个线程同时进入if语句,创建多个对象,线程不安全。

    /**
     * 懒汉式
     */
    public class Singleton {
        private static Singleton instance;
    
        private Singleton () {}
    
        public static Singleton getInstance() {
            if(instance == null) {
           instance = new Singleton();
         }
         return instance; } }

     

    3.懒汉式同步锁版

     虽然线程安全,但是锁范围较大,效率较低。

    /**
     * 懒汉线程同步锁版
     */
    class Singleton {
        private static Singleton instance;
    
        private Singleton() {}
    
        public synchronized static Singleton getInstance() {
            if(instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

     

    4.懒汉式双重检验锁版

    依然存在问题instance = new Singleton()这行在JVM大致做了如下操作:
    1.给instance分配内存
    2.调用Singleton构造函数初始化成员变量
    3.将instance对象指向分配的内存空间,执行完这一步,instance就不为null了
    JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的,所以此行不是一个原子操作
    在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,最后报错。

    class Singleton {
        private static Singleton instance;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if(instance == null) {
                synchronized(Singleton.class){
                    if(instance == null) {
                         instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }    
    

     

     5.懒汉式双重检验锁最终版

    使用volatile关键字来解决上一版的问题,在这里volatile的作用是禁止JVM的指令重排序优化,而不是利用可见性。

    /**
     * 双重检验锁最终版
     */
    
    public class Singleton{
        private volatile static Singleton instance;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    

     

     6.静态内部类版

      由于JVM特殊机制,线程安全,无效率缺陷,属于懒汉式。

    //静态内部类版
    public class Singleton { private static class SingletonHolder { private static Singleton INSTANCE = new Singleton (); } private Singleton () {} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; }

     

     7.写法最简单的单例-枚举版

    //枚举版 线程安全
    public enum EasySingleton{ INSTANCE; }
    

     

  • 相关阅读:
    Team饭来了团队作业3需求改进与系统设计
    2016012006崔啸寒 散列函数的应用及其安全性
    结对项目之四则运算
    《构建之法》第四章,第十七章所感
    2016012006小学四则运算练习软件项目报告
    读《构建之法》之一,二,十六章有感
    追梦软件路,愿不忘初心
    信息安全作业5 有关散列函数安全性的知识扩展
    结对作业:四则运算网页版
    Week4-作业1:阅读笔记与思考
  • 原文地址:https://www.cnblogs.com/zfinding/p/10512743.html
Copyright © 2020-2023  润新知