设计模式-单例模式
单例模式大家应该都很熟悉了,再重复一下它的定义:保证一个类只有一个实例,并提供一个访问它的全局访问点
下面来讨论一下实现方式
首先是最常见的懒汉式和饿汉式
饿汉式
public class Singleton1 {
private static Singleton1 instance = new Singleton1();
private Singleton1() {
}
public static Singleton1 getInstance(){
return instance;
}
}
饿汉式是程序启动即初始化,不会有线程安全的问题,不过由于不是懒加载的模式,会增加启动的负载,在一定程度上算是浪费内存
懒汉式
public class Singleton2 {
private static Singleton2 instance;
private Singleton2() {
}
public static Singleton2 getInstance(){
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}
懒汉式是在懒加载,是在需要的时候才创建。不过普通的懒汉式是非线程安全的,在多线程的情况下就需要加双锁
public class Singleton3 {
private static volatile Singleton3 instance;
private Singleton3() {
}
public static Singleton3 getInstance(){
if (instance == null) {
synchronized (Singleton3.class) {
if (instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}
需要注意的是JVM的类加载是非原子的,可能被时间片分割,所以需要volatile关键字
静态内部类
public class Singleton4 {
private Singleton4(){
}
public static Singleton4 getInstance(){
return Inner.instance;
}
private static class Inner {
private static final Singleton4 instance = new Singleton4();
}
}
这种方式运用了 classloader 的机制,类似于双锁的效果,只有 getInstance 方法第一次被调用时,JVM才加载 Inner 并初始化 instance
枚举
public enum Singleton5 {
INSTANCE;
public static Singleton5 getInstance() {
return Singleton5.INSTANCE;
}
}
在普通情况中推荐静态内部类的方式,涉及到反序列化创建对象时考虑枚举