线程安全的单例模式的几种实现方法分享
线程安全的单例模式实现有几种思路,个人认为第2种方案最优雅
- 饿汉式
- 借助内部类
- 普通加锁解决
- 双重检测
但要注意写法,如果单体模式继续扩展为N元单体模式,那就是对象池模式了
1、饿汉式单例
public class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return INSTANCE;
}
}
2、借助内部类,相对来说,这个比较省事,不过也因为是内部类,当前对象的持有也需要注意。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private final static Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
3、懒汉模式下的几种情况
- 3.1 普通加锁模式,
虽然解决了线程安全问题,但是每个线程调用getInstance都要加锁
public class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 3.2 双重检测,但要注意写法,
由于指令重排序问题的问题,所以这种写法比较安全可靠一些
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if(instance == null) {
synchronzied(Singleton.class) {
Singleton temp = instance;
if(temp == null) {
temp = new Singleton();
instance = temp
}
}
}
return instance;
}
}
- 3.3 双重检测,使用
volatile
修饰,这样的话就可以确保instance = new Singleton(); 对应的指令不会重排序
public class Singleton {
private static volatile Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
synchronzied(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
3.4 不要写出以下的代码,虽然在不是超级频繁调用的情况下以下代码也能和3.3的效果一样的正确运行
3.4 不要写出以下的代码,虽然在不是超级频繁调用的情况下以下代码也能和3.3的效果一样的正确运行
3.4 不要写出以下的代码,虽然在不是超级频繁调用的情况下以下代码也能和3.3的效果一样的正确运行
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if(instance == null) {
synchronzied(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
网友评论