# 懒汉式
| public class LazySingleton { |
| |
| private static SingletonObject singletonObject; |
| |
| |
| |
| public static SingletonObject getInstance() { |
| |
| if (singletonObject == null) { |
| |
| return new SingletonObject(); |
| |
| } |
| |
| return singletonObject; |
| |
| } |
| |
| } |
延迟加载对象,只有在用到的时候才回去创建,但是多线程情况下会有线程安全问题。
# 懒汉式 - 线程安全
| public class LazySingleton { |
| |
| private static SingletonObject singletonObject; |
| |
| |
| |
| public static synchronized SingletonObject getInstance() { |
| |
| if (singletonObject == null) { |
| |
| return new SingletonObject(); |
| |
| } |
| |
| return singletonObject; |
| |
| } |
| |
| } |
使用 synchronized 关键字加锁,虽然解决了线程安全问题,但是导致每一个线程想要获取对象都要先获取锁,但这个锁又只有在创建对象时才有用,所以非常影响性能。
# 饿汉式
| public class HungrySingleton { |
| |
| private static final SingletonObject singletonObject=new SingletonObject(); |
| |
| public static SingletonObject getInstance(){ |
| |
| return singletonObject; |
| |
| } |
| |
| } |
相比较懒汉式,饿汉式线程安全,类加载时就会创建好对象,但是问题如果该对象并不会使用,但他还是会被加载到内存中,浪费内存。
# 双重检测
| public class DoubleCheckSingleton { |
| |
| private volatile static SingletonObject singletonObject; |
| |
| public static SingletonObject getInstance(){ |
| |
| if (singletonObject==null){ |
| |
| synchronized (DoubleCheckSingleton.class){ |
| |
| if (singletonObject==null){ |
| |
| return new SingletonObject(); |
| |
| } |
| |
| } |
| |
| } |
| |
| return singletonObject; |
| |
| } |
| |
| } |
这种模式将饿汉式的 synchronized 关键字转换成代码块的形式,并在外部又加了一层 if 判断,这样创建对象时就不会有线程安全问题,并且由于外层 if 的存在,后续获取对象的操作也不会受 synchronized 影响。
# 枚举模式
| public enum EnumSingleton { |
| |
| INSTANCE; |
| |
| public String doSomething(){ |
| |
| return "something..."; |
| |
| } |
| |
| } |