Java设计模式之单例模式
前言
Java中单例模式有懒汉单例模式,饿汉单例模式,双重检查加锁单例模式,静态内部类单例模式;下面会用具体的代码来介绍他们的优缺点,没有最好的只有最合适自己的,结合自己的业务选择适合自己的单例模式。
懒汉单例模式
懒顾名思义需要的时候采取拿。这是典型的以时间换空间的场景;getInstance()方法加锁是防止多线程不安全。
public class LazySingleton {
private static LazySingleton singleton = null;
// 防止外部实例化
private LazySingleton(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized LazySingleton getInstance() {
if (singleton == null) {
singleton = new LazySingleton();
}
return singleton;
}
}
饿汉单例模式
饿顾名思义不要后面要不要,先拿来再说。这是典型的以空间换时间的场景;HungrySingleton类加载后就实例了该对象了。
public class HungrySingleton {
private static HungrySingleton singleton =
new HungrySingleton();
// 防止外部实例化
private HungrySingleton() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static HungrySingleton getInstance() {
return singleton;
}
}
双重检查加锁单例模式
在懒汉单例模式的getIntance()方法有个加锁的操作,这样能防止多线程的不安全情况,但是你有木有考虑到代码执行效率的问题,为了让代码效率更高,双重检查加锁单例模式对于懒汉单例模式是个更好的选择。
public class CheckSingleton {
private static CheckSingleton singleton;
private CheckSingleton() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static CheckSingleton getInstance() {
if (singleton == null) { // 不加锁判断
synchronized (CheckSingleton.class) {
if (singleton == null) { // 加锁后 二次判断
singleton = new CheckSingleton();
}
}
}
return singleton;
}
}
静态内部类单例模式
静态内部类也叫类级内部类,这个模式使用了多线程缺省同步锁的知识,很巧妙地同时实现了延迟加载和线程安全。对于饿汉单例更节省空间,对于懒汉单例模式更高效。
public class ClassLevelSingleton {
private ClassLevelSingleton(){}
private static class SingletonHolder {
/*
* * 静态初始化器,由JVM来保证线程安全
*/
private static ClassLevelSingleton instance =
new ClassLevelSingleton();
}
public static ClassLevelSingleton getInstance() {
return SingletonHolder.instance;
}
}
如果你觉得不错的话,你还可以看demo