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();
        }
    }
    
  • 相关阅读:
    图片延迟加载方法
    mongodb常用命令
    未知尺寸元素水平垂直居中:
    nodejs学习之加密
    nodejs学习之events的使用
    nodejs学习之events
    学习Nodejs之mysql
    PHP之几道面试题
    Jquery学习插件之手风琴
    我的第一篇博客
  • 原文地址:https://www.cnblogs.com/liuyang0/p/6613152.html
Copyright © 2011-2022 走看看