单例模式
定义
确保一个类只有一个实例,并且只提供一个全局访问点。
饿汉模式
加载类的时候就实例化对象
代码语言:javascript复制/**
* 饿汉模式
* @author huangy on 2019-05-25
*/
public class HunarySingle {
/**
* 在静态初始化器中创建单件。这段代码保证了线程安全
* 加载类的时候就初始化了属性。等到线程访问该属性的时候,属性已经初始化好了。从而保证线程安全
*/
private static HunarySingle hunarySingle = new HunarySingle();
private HunarySingle() {
}
public static HunarySingle getInstance() {
return hunarySingle;
}
}
懒汉模式
代码语言:javascript复制// 存在线程安全的问题
public class LazySingle {
private static LazySingle single;
private LazySingle() {
}
public LazySingle getInstance() {
if (single == null) {
single = new LazySingle();
}
return single;
}
}
代码语言:javascript复制// 整个方法同步的方式,存在性能问题
public class LazySingle {
private static LazySingle single;
private LazySingle() {
}
public synchronized LazySingle getInstance() {
if (single == null) {
single = new LazySingle();
}
return single;
}
}
代码语言:javascript复制// 利用双重检查的方式时间,提高并发性
/**
* @author huangy on 2019-05-25
*/
public class DoubleCheckSingleton {
// 利用volatile保证内存可见性,线程可以立刻看到singleton值的变更
private volatile static DoubleCheckSingleton singleton;
public DoubleCheckSingleton getInstance() {
if (singleton == null) {
/**
* 优点就是:只有第一次多线程同时访问的时候,才会执行同步块代码,
* 后面的多线程访问,直接在singleton == null判断false,然后就返回了singleton了
*/
synchronized (DoubleCheckSingleton.class) {
if (singleton == null) {
singleton = new DoubleCheckSingleton();
}
}
}
return singleton;
}
}
静态内部类方式实现
既能够延迟加载,又保证线程安全
代码语言:javascript复制public class Singletion {
private Singletion () {}
private static class InnerSingletion {
private static Singletion single = new Singletion();
}
// 调用getInstance方法的时候,会加载InnerSingletion内部类,并且初始化single属性,然后线程才能开始访问。这样子保证了线程安全,并且实现了懒加载
public static Singletion getInstance(){
return InnerSingletion.single;
}
}