Java实现单例模式的几种常用方式:
1. 饿汉式
实现最简单,缺点是没有使用时就创建,浪费内存。
public class SingletonHungry {
private static final SingletonHungry INSTANCE = new SingletonHungry();
private SingletonHungry() {
}
public static SingletonHungry getInstance() {
return INSTANCE;
}
}
2. 懒汉式 线程安全
获取对象时再实例化,为了保证线程安全,使用 synchronized
关键字进行同步,缺点是方法级的同步使效率较低。
public class SingletonLazy {
private static SingletonLazy instance;
private SingletonLazy() {
}
public static synchronized SingletonLazy getInstance() {
if (instance == null) {
instance = new SingletonLazy();
}
return instance;
}
}
3. 双重检验锁
为了提升懒汉式的效率,方法体上的锁去掉,先判断是否已经实例化看,如果没有,在真正创建对象时加锁,进入锁后还有一次判断,这是因为在多线程并发条件下,一个线程拿到锁执行实例化操作,其他线程等待,唤醒后,需要先判断是否已经创建完成了,防止多次创建。
public class SingletonDoubleCheck {
private volatile static SingletonDoubleCheck singleton;
private SingletonDoubleCheck (){}
public static SingletonDoubleCheck getSingleton() {
if (singleton == null) {
synchronized (SingletonDoubleCheck.class) {
if (singleton == null) {
singleton = new SingletonDoubleCheck();
}
}
}
return singleton;
}
}
4. 静态内部类
此方式是通过类加载机制保证单例,虚拟机会保证类构造器在多线程环境下被正确的加锁、同步,如果多个线程同时去初始化一个类,只会有一个线程执行构造器,其他线程都要等待。
public class SingletonStaticInnerClass {
private static class SingletonHolder {
private static final SingletonStaticInnerClass INSTANCE =
new SingletonStaticInnerClass();
}
private SingletonStaticInnerClass (){}
public static final SingletonStaticInnerClass getInstance() {
return SingletonHolder.INSTANCE;
}
}
5. 枚举
用法简单,还可以方式反射方式创建多个实例,是JDK1.5以后才支持的。
public enum SingletonEnum {
Instance;
private SingletonEnum() {
System.out.println("init ... ");
}
public static void main(String[] args) {
SingletonEnum b1 = SingletonEnum.Instance;
SingletonEnum b2 = SingletonEnum.Instance;
SingletonEnum b3 = SingletonEnum.Instance;
System.out.println(b1 == b2);
System.out.println(b1 == b3);
}
}
网友评论