归类 : Java
文集 : 浅谈

本文对Java中常见的单例模式写法做了小结

饿汉法

第一次引用该类就创建对象实例

    public class Singleton {   
        private static singleton = new Singleton();
        private Singleton() {}
        public static Singleton getSingleton(){
            return singleton;
        }
    }

懒汉法

简单写法

简单写法即不考虑线程安全的写法,适用于非多线程编程;与饿汉法的唯一区别在于调用getSingleton()方法会进行判断是否新建实例

    public class Singleton {
        private static Singleton singleton = null;
        private Singleton(){}
        public static Singleton getSingleton() {
            if(singleton == null) 
                singleton = new Singleton();
            return singleton;
        }
    }

双重检查锁写法

上例子中多线程环境下非空判断if(singleton == null)会出问题;在getSingleton()方法中,进行两次null检查即为双重检查锁,因为singleton只要初始化一次即不再为空,对singleton进行非null检查是非常快速的。因此在加锁前进行一次非null检查可减少绝大多数的加锁操作。

    public class Singleton {
        private static volatile Singleton singleton = null;
        private Singleton(){}
        public static Singleton getSingleton(){
            if(singleton == null){
                synchronized (Singleton.class){
                    if(singleton == null){
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }    
    }

静态内部类写法

此写法是延时加载且线程安全

    public class Singleton {
        private static class Holder {
            private static Singleton singleton = new Singleton();
        }
        private Singleton(){}
        public static Singleton getSingleton(){
            return Holder.singleton;
        }
    }

枚举写法

Effective Java推荐的最优写法;

1.线程安全;2.防止反射强行调用构造器;3.提供了自动序列化机制,防止反序列化的时候创建新的对象

    public enum Singleton {
        INSTANCE;
        private String name;
        public String getName(){
            return name;
        }
        public void setName(String name){
            this.name = name;
        }
    }

以上