保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式(Singleton)的目的是为了保证在一个进程中,某个类有且仅有一个实例。
- 饿汉式
在声明之初就指定对象实例化。
public class Singleton {
// 静态字段引用唯一实例:
private static final Singleton INSTANCE = new Singleton();
// private构造方法保证外部无法实例化:
private Singleton() {
}
// 通过静态方法返回实例:
public static Singleton getInstance() {
return INSTANCE;
}
}
2.懒汉式
在真正调用的时候才实例化对象。
public class Singleton {
private static Singleton INSTANCE = null;
private Singleton() {
}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
在单线程下这种懒汉式是没有问题的,但是在多线程下这种方式是线程不安全的,饿汉式会有JVM实例化替我们保证线程安全,懒汉式要进行以下改造。
public class Singleton {
private static volatile Singleton INSTANCE = null;
private Singleton() {
}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
为什么要这么做呢?
因为实例化表面上看起来是一个语句,但是里面涉及到了分配内存空间,初始化对象,将对象指向刚分配的内存空间的操作。有些编译器为了性能的原因,可能会将第二步和第三步进行重排序,那么使用volatile后重排序被禁止,所有的写(write)操作都将发生在读(read)操作之前。
3.内部类
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
private static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
内部类这种形式支持懒加载,也线程安全,推荐使用
网友评论