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();
    }
}

posted on 2017-03-24 20:00  liuyang0  阅读(1192)  评论(0编辑  收藏  举报

导航

Flag Counter