使用单例需要注意的关键点
- 将构造函数访问修饰符设置为private
- 通过一个静态方法或者枚举返回单例类对象
- 确保单例类的对象有且只有一个,特别是在多线程环境下
- 确保单例类对象在反序列化时不会重新构建对象
单例模式的几种写法
- 饿汉式(静态常量)
class Singleton{
private Singleton(){
}
private final static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
- 饿汉式(静态代码块)
class Singleton {
private Singleton() {
}
private static Singleton instance;
static {
instance = new Singleton();
}
public static Singleton getInstance() {
return instance;
}
}
- 懒汉式(线程不安全)
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 懒汉式(线程安全,同步方法)
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 懒汉式(双重校验,线程安全,效率较高,推荐使用)
class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 静态内部类完成,推荐使用
class Singleton {
private Singleton() {
}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
- 使用枚举,推荐使用
enum Singleton{
INSTANCE;
public void doSomething(){
System.out.println("do something");
}
}