单例模式的5种实现方法-设计模式
1.双重检查的方式
特点:线程安全;延迟加载;效率较高,推荐使用
/**
* 双重检查的方式,线程安全;延迟加载;效率较高。
* @author LENOVO
*
*/
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
2.静态内部类
特点:延时加载,线程安全,效率高
/**
* 静态内部类的方式,延时加载,线程安全,效率高
* @author LENOVO
*/
public class Singleton2 {
private Singleton2() {}
private static class SingletonInstance {
private static final Singleton2 INSTANCE = new Singleton2();
static {
System.out.println(INSTANCE);
}
}
public static Singleton2 getInstance() {
System.out.println("****");
return SingletonInstance.INSTANCE;
}
public static void main(String[] args) {
Singleton2.getInstance();
/**
* 为什么说是延时加载呢?
* 静态变量在类加载完成以后就完成了初始化,但在本例当中
* 在没有调用getInstance方法之前,SingletonInstance类是不会被虚拟机加载的。
* 当调用getInstance方法,执行return SingletonInstance.INSTANCE;语句时,
* 虚拟机才会去加载SingletonInstance类,并完成INSTANCE实例的初始化。
*/
}
}
3.饿汉式(静态常量)
/**
* 饿汉式(静态常量),在类加载的时候完成初始化
* @author LENOVO
*/
public class Singleton3 {
private final static Singleton3 INSTANCE = new Singleton3();
private Singleton3(){}
public static Singleton3 getInstance(){
return INSTANCE;
}
}
4.懒汉式(延时加载【不推荐用】)
/**
* 懒汉式(延时加载【不推荐用】)
* @author LENOVO
*
*/
public class Singleton4 {
private static Singleton4 Singleton4;
private Singleton4() {}
/**
* 线程不安全
* @return
*/
public static Singleton4 getInstance() {
if (Singleton4 == null) {
Singleton4 = new Singleton4();
}
return Singleton4;
}
/**
* 线程安全,但是效率底
* @return
*/
public static synchronized Singleton4 getInstance2() {
if (Singleton4 == null) {
Singleton4 = new Singleton4();
}
return Singleton4;
}
/**
* 线程不安全效率底,这种方法不能起到线程同步的效果
* @return
*/
public static Singleton4 getInstance3() {
if (Singleton4 == null) {
synchronized (Singleton4.class) {
Singleton4 = new Singleton4();
}
}
return Singleton4;
}
}
5.枚举实现单例模式
枚举的方式实现是最安全的
public enum Singleton5 {
INSTANCE;
public int i = 0;
public void leaveTheBuilding() {
i++;
System.out.println("我现在是单例,这是我第"+i+"次调用!!");
}
// 调用这样子调用
public static void main(String[] args) {
for(int z = 0 ; z<10 ;z++){
Singleton5 demo = Singleton5.INSTANCE;
demo .leaveTheBuilding();
}
}
}
fixed
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。