使用场景:
- 需要频繁的进行创建和销毁的对象;
- 创建对象时耗时过多或耗费资源过多,但又经常用到的对象;
- 工具类对象;
- 频繁访问数据库或文件的对象。
1)饿汉先吃
饿汉式(静态常量)[可用]
public class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return INSTANCE;
}
}
优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
缺点:在类装载的时候就完成实例化,没有达到 Lazy Loading 的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。
2)懒汉不安全
懒汉式(线程不安全)[不可用]
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
这种写法起到了 Lazy Loading 的效果,但只能在单线程下使用。在多线程环境下不可使用这种方式。
3)懒汉同步方法【不可用】
懒汉式(线程安全,同步方法)[不推荐用]
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
解决上面第三种实现方式的线程不安全问题,做个线程同步就可以了,于是就对 getInstance() 方法进行了线程同步//低效率
4)懒汉双重检查【推荐使用】
双重检查[推荐用]
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;
}
优点:线程安全;延迟加载;效率较高。
5)饿汉内部类-lazy【推荐使用】
//相比于普通的饿汉模式,通过内部类,完成了延迟加载
public class Singleton {
private Singleton() {}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
6)饿汉枚举
public enum Singleton {
INSTANCE;
}避免多线程同步问题,而且还能防止反序列化重新创建新的对象
原文:https://blog.csdn.net/zoctan/article/details/79652329