一、饿汉式实现单例模式
1、线程安全的,类变量在类初始化过程中会被收集进class initialize <client>()方法中,JVM保证该方法能够百分之百保持同步。
2、没有实现懒加载,不管对象有没有使用,始终占用内存资源。
class Singleton{
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
二、懒汉式实现单例模式
1、实现懒加载,在对象没有被使用时,不会占用内存资源。
2、线程不安全。
class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
三、懒汉式 + 同步方法实现单例模式
synchronized关键字天生的排他性导致获取对象方法只能在同一时刻被一个线程访问,性能低下。
class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
四、懒汉式 + 双重检测 + 同步代码块 + volatile关键字实现单例模式
1、允许多个线程同时执行获取对象方法。
2、多线程情况下有可能引起空指针异常。比如在Singleton的构造函数中,需要实例化Connection和Socket对象,由于JVM重排序,有可能出现instance最先被实例化,而Connection和Socket并未完成实例化,未完成实例化的实例调用其方法将抛出空指针异常。使用volatile关键字禁止指令重排序,保证单例对象完全实例化。
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;
}
}
五、静态内部类实现单例模式
在静态内部类中进行实例化,当静态内部类被主动引用时的时候才会创建实例,Singleton实例的创建过程在程序编译时期收集到<clinit>()方法中,JVM保证线程安全。
class Singleton {
private Singleton() {
}
private static class Holder {
private static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return Holder.instance;
}
}
六、内部枚举类实现单例模式
1、枚举类不允许被继承,且只能被实例化一次,是线程安全的。
2、内部枚举类可实现懒加载。
class Singleton {
private Singleton() {
}
private enum EnumHolder {
INSTANCE;
private Singleton instance;
EnumHolder() {
this.instance = new Singleton();
}
}
public static Singleton getInstance() {
return EnumHolder.INSTANCE.instance;
}
}