zoukankan      html  css  js  c++  java
  • Java单例模式的各种实现(饿汉、懒汉、静态内部类、static代码块、enum枚举类型)

    饿汉模式

    饿汉模式就是立即加载,在方法调用前,实例就已经被创建了,所以是线程安全的。

    public class MyObject1 {
        private static MyObject1 myObject1 = new MyObject1();
        private MyObject1() {}
        public static MyObject1 getInstance() {
            return myObject1;
        }
    }
    

    懒汉模式

    懒汉就是延迟化加载,当需要使用的时候才进行实例化。

    线程不安全

    public class MyObject2 {
        private static MyObject2 myObject2;
        private MyObject2() {}
        public static MyObject2 getInstance() {
            if (myObject2 == null) {
                myObject2 = new MyObject2();
            }
            return myObject2;
        }
    }
    

    线程安全

    线程安全但是效率低下

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

    使用DCL双检查锁,线程安全而且效率得到提高,只将进行实例化的代码进行加锁。

    public class MyObject4 {
        private volatile static MyObject4 myObject4;
        private MyObject4() {}
        public static MyObject4 getInstance() {
            if (myObject4 == null) {
                synchronized (MyObject4.class) {
                    if (myObject4 == null) {
                        myObject4 = new MyObject4();
                    }
                }
            }
            return myObject4;
        }
    }
    

    使用静态内部类

    线程安全,也是一种懒加载模式。
    静态内部类中的静态成员只在第一次使用的时候加载,因此保证了线程安全。

    public class MyObject5 {
        private static class MyObject5Handle {
            private static MyObject5 myObject5 = new MyObject5();
        }
        private MyObject5() {}
        public static MyObject5 getInstance() {
            return MyObject5Handle.myObject5;
        }
    }
    

    使用static代码块

    由于static代码块中内容在类加载的时候就执行了,因此保证了线程安全。

    public class MyObject6 {
        private static MyObject6 instance = null;
        private MyObject6() {}
        static {
            instance = new MyObject6();
        }
        public static MyObject6 getInstance() {
            return instance;
        }
    }
    

    使用enum枚举

    JVM会保证enum不能被反射并且构造器方法只执行一次,因此该单例是线程安全的。

    public class MyObject7 {
        private enum MyEnumSingleton {
            enumFactory;
            private MyObject7 myObject7;
            private MyEnumSingleton() {
                myObject7 = new MyObject7();
            }
            public MyObject7 getInstance() {
                return myObject7;
            }
        }
        public static MyObject7 getInstance() {
            return MyEnumSingleton.enumFactory.getInstance();
        }
    }
    
  • 相关阅读:
    文章评论:级数中达朗贝尔判别法和柯西判别法之间的关系研究 By 彭军
    解析函数论 Page 22 达朗贝尔判别法 VS 柯西判别法
    解析函數論 Page 28 連續復變函數的最簡單的性質
    #2066:一个人的旅行(Dijkstra算法入门题)
    #2072 单词数(字符串流使用)
    传统的DOM渲染方式 吴小明
    【闭包】closure 吴小明
    报文 吴小明
    节流和防抖 吴小明
    什么是模块化?它有什么好处?常用的模块化开发的方案 吴小明
  • 原文地址:https://www.cnblogs.com/liuyang0/p/6613152.html
Copyright © 2011-2022 走看看