第一种饿汉式:缺点:项目启动就加载比较占用内存空间
public class SingletonObject1 { /** * can't lazy load. */ private static final SingletonObject1 instance = new SingletonObject1(); private SingletonObject1() { //empty } public static SingletonObject1 getInstance() { return instance; } }
第二种:懒汉式,线程不安全,多线程情况下会出现多个实例对象。
public class SingletonObject2 { private static SingletonObject2 instance; private SingletonObject2() { //empty } public static SingletonObject2 getInstance() { if (null == instance) instance = new SingletonObject2(); return SingletonObject2.instance; } }
第三种:懒汉式,加锁,缺点,效率低下
public class SingletonObject3 { private static SingletonObject3 instance; private SingletonObject3() { //empty } public synchronized static SingletonObject3 getInstance() { if (null == instance) instance = new SingletonObject3(); return SingletonObject3.instance; } }
第四种:双重校验,构造如果初始化数据会出现空指针情况。
public class SingletonObject4 { private static SingletonObject4 instance; private SingletonObject4() { //--- } //double check public static SingletonObject4 getInstance() { if (null == instance) { synchronized (SingletonObject4.class) { if (null == instance) instance = new SingletonObject4(); } } return SingletonObject4.instance; } }
第五种:增加 volatile关键字,没有线程安全问题。
public class SingletonObject5 { private static volatile SingletonObject5 instance; private SingletonObject5() { // } //double check add volatile public static SingletonObject5 getInstance() { if (null == instance) { synchronized (SingletonObject4.class) { if (null == instance) instance = new SingletonObject5(); } } return SingletonObject5.instance; } }
第六种:更优雅更有效,内部类方式
public class SingletonObject6 { private SingletonObject6() { } private static class InstanceHolder { private final static SingletonObject6 instance = new SingletonObject6(); } public static SingletonObject6 getInstance() { return InstanceHolder.instance; } }
第七种方式:枚举类。
public class SingletonObject7 { private SingletonObject7() { } private enum Singleton { INSTANCE; private final SingletonObject7 instance; Singleton() { instance = new SingletonObject7(); } public SingletonObject7 getInstance() { return instance; } } public static SingletonObject7 getInstance() { return Singleton.INSTANCE.getInstance(); } public static void main(String[] args) { IntStream.rangeClosed(1, 100) .forEach(i -> new Thread(String.valueOf(i)) { @Override public void run() { System.out.println(SingletonObject7.getInstance()); } }.start()); } }