zoukankan      html  css  js  c++  java
  • java单例之enum实现方式

    传统的两私有一公开(私有构造方法、私有静态实例(懒实例化/直接实例化)、公开的静态获取方法)涉及线程安全问题(即使有多重检查锁也可以通过反射破坏单例),

    目前最为安全的实现单例的方法是通过内部静态enum的方法来实现,因为JVM会保证enum不能被反射并且构造器方法只执行一次。

    实现方法如下:

    /**
     * 使用枚举的单例模式
     *
     * @author yzl
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public class EnumSingleton{
        private EnumSingleton(){}
        public static EnumSingleton getInstance(){
            return Singleton.INSTANCE.getInstance();
        }
        
        private static enum Singleton{
            INSTANCE;
            
            private EnumSingleton singleton;
            //JVM会保证此方法绝对只调用一次
            private Singleton(){
                singleton = new EnumSingleton();
            }
            public EnumSingleton getInstance(){
                return singleton;
            }
        }
    }

    测试方法:

    public static void main(String[] args) {
        EnumSingleton obj1 = EnumSingleton.getInstance();
        EnumSingleton obj2 = EnumSingleton.getInstance();
        //输出结果:obj1==obj2?true
        System.out.println("obj1==obj2?" + (obj1==obj2));
    }

    扩展应用,观察下面的例子

    public class Test{
      //初始化一些东西
      static{
        
       }
    }

    这是一个很常见的类内部的静态资源初始化的写法(其实也就是单例的另外一种表现-只执行一次),但是将代码都写在static块下会看起来很不优雅,可以利用上面的enum单例模式来进行初始化操作。

    见例子:

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 初始化的优雅实现
     * 可以在static处调用,
     * 也可以在普通方法里调用,都保证只初始化一次
     * 
     * 当然将enum块的代码直接放到StaticInitTest类的private static 方法里做也是可以的
     *
     * @author yzl
     * @see [相关类/方法](可选)
     * @since [产品/模块版本] (可选)
     */
    public class StaticInitTest {
        private static List<Integer> dataList = null;
        
        static{
            dataList = Singleton.INSTANCE.init();
        }
        
        /**
         * 
         * 单例模式来填充数据
         *
         * @author yzl
         * @see [相关类/方法](可选)
         * @since [产品/模块版本] (可选)
         */
        private static enum Singleton {
            INSTANCE;
            private List<Integer> list;
            
            private Singleton(){
                fillData();
            }
            /**
             * 
             * 初始化数据
             *
             * @see [相关类/方法](可选)
             * @since [产品/模块版本](可选)
             */
            private void fillData(){
                list = new ArrayList<Integer>(5);
                for(int i =1; i<6; i++){
                    list.add(i);
                }
            }
    
            /**
             * 
             * 初始化的入口
             *
             * @see [相关类/方法](可选)
             * @since [产品/模块版本](可选)
             */
            public List<Integer> init(){
                return list;
            }
        }
    }
  • 相关阅读:
    django orm中filter(条件1).filter(条件2)与filter(条件1,条件2)的区别 哈欠涟涟的日志 网易博客
    提示:ERROR 1044 (42000): Access denied for user
    取消选中的区域
    1.XML复习、HTML DOM 复习 2.simpleXML方式解析XML 3.XPath 4,MVC
    JSP的内置对象(session)
    每月自评之三:2013年3月
    HDU1405:The Last Practice
    一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重复,且都为小写字母),然后与字母表中其他字母一起填入至一个5x5的方阵中,填入方法如下:
    一个经典实用的 IPtables Shell 脚本
    static class 静态类
  • 原文地址:https://www.cnblogs.com/yangzhilong/p/6148639.html
Copyright © 2011-2022 走看看