zoukankan      html  css  js  c++  java
  • 枚举实现单例模式

    1.引言

    单元素的枚举类型已经成为实现Singleton的最佳方法
                          -- 出自 《effective java》

    2.单例模式的特点

    • 单例模式三个主要特点:
      1、构造方法私有化;
      2、实例化的变量引用私有化;
      3、获取实例的方法共有。

    3. 常用的单例模式

    1.单例的饿汉模式

     1   public class Singleton {
     2     /*
     3      * 利用静态变量来记录Singleton的唯一实例
     4      * 直接初始化静态变量,这样就可以确保线程安全了
     5      */
     6     private static Singleton uniqueInstance = new Singleton();
     7
     8     /*
     9      * 构造器私有化,只有Singleton类内才可以调用构造器
    10      */
    11     private Singleton(){
    12
    13     }
    14
    15     public static Singleton getInstance(){
    16         return uniqueInstance;
    17     }
    18
    19 }
    

    2.懒汉的双重加锁机制

     1 public class Singleton {
     2     /*
     3      * 利用静态变量来记录Singleton的唯一实例
     4      * volatile 关键字确保:当uniqueInstance变量被初始化成Singleton实例时,
     5      * 多个线程正确地处理uniqueInstance变量
     6      *
     7      */
     8     private volatile static Singleton uniqueInstance;
     9
    10     /*
    11      * 构造器私有化,只有Singleton类内才可以调用构造器
    12      */
    13     private Singleton(){
    14
    15     }
    16
    17     /*
    18      *
    19      * 检查实例,如果不存在,就进入同步区域
    20      */
    21     public static Singleton getInstance(){
    22         if(uniqueInstance == null){
    23             synchronized(Singleton.class){    //进入同步区域
    24                 if(uniqueInstance == null){     //在检查一次,如果为null,则创建
    25                     uniqueInstance  = new Singleton();
    26                 }
    27             }
    28         }
    29
    30         return uniqueInstance;
    31     }
    32
    33 }
    

    3.静态内部类

    public class Singleton {    
        private static class LazyHolder {    
           private static final Singleton INSTANCE = new Singleton();    
        }    
        private Singleton (){}    
        public static final Singleton getInstance() {    
           return LazyHolder.INSTANCE;    
        }    
    }
    

    4.为什么使用单例

    4.1 私有化构造器并不保险

        《effective java》中只简单的提了几句话:“享有特权的客户端可以借助AccessibleObject.setAccessible方法,通过反射机制调用私有构造器。如果需要低于这种攻击,可以修改构造器,让它在被要求创建第二个实例的时候抛出异常。
    

    4.2序列化问题

        任何一个readObject方法,不管是显式的还是默认的,它都会返回一个新建的实例,这个新建的实例不同于该类初始化时创建的实例。”当然,这个问题也是可以解决的,想详细了解的同学可以翻看《effective java》第77条:对于实例控制,枚举类型优于readResolve
    

    4.3 枚举单例示例

    public enum  EnumSingleton {
        INSTANCE;
        public EnumSingleton getInstance(){
            return INSTANCE;
        }
    }
    

    完整的枚举单例

    
    public class User {
        //私有化构造函数
        private User(){ }
     
        //定义一个静态枚举类
        static enum SingletonEnum{
            //创建一个枚举对象,该对象天生为单例
            INSTANCE;
            private User user;
            //私有化枚举的构造函数
            private SingletonEnum(){
                user=new User();
            }
            public User getInstnce(){
                return user;
            }
        }
     
        //对外暴露一个获取User对象的静态方法
        public static User getInstance(){
            return SingletonEnum.INSTANCE.getInstnce();
        }
    }
    
    public class Test {
        public static void main(String [] args){
            System.out.println(User.getInstance());
            System.out.println(User.getInstance());
            System.out.println(User.getInstance()==User.getInstance());
        }
    }
    结果为true
    

    5.总结

    至此,相信同学们应该能明白了为什么Joshua Bloch说的“单元素的枚举类型已经成为实现Singleton的最佳方法”了吧。



    作者:多彩海洋
    链接:https://www.jianshu.com/p/d35f244f3770
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    巧用加密方法保障电子邮件系统安全 狼人:
    网管员注意:保障邮件安全的七条措施 狼人:
    全面剖析DNS 0DAY攻击、威胁以及防治 狼人:
    简述:电子邮件安全发展 狼人:
    IE漏洞致数百万用户中招 快用瑞星卡卡打补丁 狼人:
    警惕可执行文件:三类危险TXT类型文件 狼人:
    安全使用电子邮件十三法 狼人:
    提高IE和Email的安全性的四步骤 狼人:
    了解电子邮件加密 保证隐私内容安全 狼人:
    防不胜防 了解DNS缓存中毒攻击原理 狼人:
  • 原文地址:https://www.cnblogs.com/cnndevelop/p/12739276.html
Copyright © 2011-2022 走看看