- 首页 > it技术 > >
- 懒汉模式
/**
* @Description 懒汉模式 实现了延迟加载,但是效率较低
*/
public class LazySingleton {private static LazySingleton lazySingleton;
private LazySingleton(){}public synchronized static LazySingleton getLazySingleton(){
if(lazySingleton == null){
lazySingleton = new LazySingleton();
}
return lazySingleton;
}public static void main(String[] args) {
LazySingleton h1 = LazySingleton.getLazySingleton();
LazySingleton h2 = LazySingleton.getLazySingleton();
System.out.println(h1==h2);
}
}
- 饿汉模式
1
/**
* @Description饿汉模式
* 类加载时完成实例化,避免多线程同步问题
*/
public class HungrySingleton {private static HungrySingleton singleton = new HungrySingleton();
private HungrySingleton(){
}public static HungrySingleton getSingleton(){
return singleton;
}public static void main(String[] args) {
HungrySingleton h1 = HungrySingleton.getSingleton();
HungrySingleton h2 = HungrySingleton.getSingleton();
System.out.println(h1==h2);
}
}
- 双重校验锁模式
/**
* @description: 1.懒加载, 2 volatile 保证了指令不会重排
*/
public class DoubleCheckSingleton {private volatile static DoubleCheckSingleton singleton;
private DoubleCheckSingleton() {
}public static DoubleCheckSingleton getInstance(){
if(singleton == null){
synchronized (DoubleCheckSingleton.class){
if(singleton == null){
singleton = new DoubleCheckSingleton();
}
}
}
return singleton;
}public static void main(String[] args) {
DoubleCheckSingleton d1 = DoubleCheckSingleton.getInstance();
DoubleCheckSingleton d2 = DoubleCheckSingleton.getInstance();
System.out.println(d1==d2);
}} singleton = new DoubleCheckSingleton();
实际过程分为3步
1.为singleton分配内存空间
2.初始化singleton
3.singleton指向分配的内存地址
由于jvm具有指令重排的特性,因此指令可能变成1->3->2。指令重排在单线程下不会出现问题,但多线程环境中会造成一个线程获得没有初始化的实例
使用volatile可以禁止指令重排,在多线程环境下也能正常运行
- 内部类模式
/***
* @description: 外部类加载时不会加载内部类,使用内部类时才会加载, 保证了懒加载
* 类加载时实例化对象,不会造成线程安全问题
*/
public class InnerClassSingleton {private InnerClassSingleton(){}private static class innerInstance {
private static final InnerClassSingleton singleton = new InnerClassSingleton();
}public static InnerClassSingleton getInstance(){
return innerInstance.singleton;
}public static void main(String[] args) {
InnerClassSingleton i1 = InnerClassSingleton.getInstance();
InnerClassSingleton i2 = InnerClassSingleton.getInstance();
System.out.println(i1==i2);
}
}
推荐阅读