zoukankan      html  css  js  c++  java
  • 设计模式之单例模式(Java)

    单例模式

    问题

    多线程操作同一对象保证对象的一致性

    解决思路

    只有一次实例化过程,产生一个实例化对象,并提供返回该对象的方法。

    单例模式的分类

    1 饿汉式

    在加载类的时候就产生实例对象

    public class HungerySingleton {
    
        /**
         * 在加载说就产生了实例对象
         */
        private static HungerySingleton instance = new HungerySingleton();
    
        private HungerySingleton(){
    
        }
        /**
         * @return 返回实例对象
         */
        public static HungerySingleton getInstance(){
            return instance;
        }
    }
    

    线程安全性:在加载时就已经实例化,所以只有一次实例化,线程是安全的。

    不是懒加载

    性能不好

    2 懒汉式

    在加载类时不声明实例对象,当使用该对象时才会实例化对象,不过对象也只能实例化一次。

    public class HoonSinglenton {
        /**
         * 在加载时只声明变量不产生了实例对象
         */
        private static HoonSinglenton instance = null;
        private HoonSinglenton(){
    
        }
        /**
         * @return 返回实例对象
         */
        public static HoonSinglenton getInstance(){
            if (instance == null){
                instance = new HoonSinglenton();
            }
            return instance;
        }
    }
    

    **线程安全性:不安全,不能保证实例对象的唯一性。**在多线程访问时,如果有两个线程同时进入if判断那么这两个线程获取的对象不是同一对象,不符合单例模式的定义。

    是懒加载

    性能好

    3 懒汉式+同步方法

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

    线程安全性:安全

    是懒加载

    性能不好:synchronized修饰的方法在多线程访问时会退化成串行执行。

    4 DCL(Double-Check-Locking)

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

    性能比较好

    懒加载

    保证线程安全性

    缺点:会因为指令重排序,引起空指针异常

    5 volatile + DCL

    private volatile static DCL instance = null;
    

    DCL解决方案

    6 Holder

    使用比较广泛的一种单例模式

    在声明类时,成员变量中不声明实例变量,而放到内部静态类中,在静态类中实例化,避免懒汉式中加锁的问题。

    public class HolderSinglenton {
        
        private HolderSinglenton(){}
        
        private static class Holder{
            private static HolderSinglenton instance = new HolderSinglenton();
        }
        
        public static HolderSinglenton getInstance(){
            return Holder.instance;
        }
    }
    

    7 枚举

    Effective Java推荐该方法

    public class EnumSingletonDemo {
    
        private EnumSingletonDemo(){}
    
        private enum EnumHolder{
            /**
             * 单例对象
             */
            INSTANCE;
            private EnumSingletonDemo instance;
            EnumHolder(){
                this.instance = new EnumSingletonDemo();
            }
            private EnumSingletonDemo getInstance(){
                return instance;
            }
        }
        
        public static EnumSingletonDemo getInstance(){
            return EnumHolder.INSTANCE.getInstance();
        }
    }
    

    代码中的的枚举类型是一个内部类,内部类在Java中使用是懒加载只有使用时才会加载。加载EnumSingletonDemo类不会引起内部类的加载。

  • 相关阅读:
    jQuery Deferred和Promise的使用介绍:
    asp.net客户端IP跟踪
    jquery常用的一些方法
    前端音频流播放
    c# Http请求下载二进制流文件
    iView表格行验证问题
    【已解决】Https请求—未能创建 SSL/TLS 安全通道
    安全开发规范
    数据库设计规范
    高性能开发规范
  • 原文地址:https://www.cnblogs.com/wf614/p/11673811.html
Copyright © 2011-2022 走看看