目录
- 单例模式
- 1.饿汉式(线程安全)
- 2.懒汉式(通过synchronized修饰获取实例的方法保证线程安全)
- 3.双重校验锁的方式实现单例模式
- 4.静态内部类方式实现单例模式【推荐】
单例模式
1.饿汉式(线程安全)
package 并发的例子.单例模式;
public class Singleton1 {private static final Singleton1 INSTANCE = new Singleton1();private Singleton1() {}public static Singleton1 getInstance() {return INSTANCE;}public static void main(String[] args) {Singleton1 instance1 = Singleton1.getInstance();Singleton1 instance2 = Singleton1.getInstance();Singleton1 instance3 = Singleton1.getInstance();System.out.println(instance1 == instance2);System.out.println(instance2 == instance3);System.out.println(instance1 == instance3);}
}
2.懒汉式(通过synchronized修饰获取实例的方法保证线程安全)
package 并发的例子.单例模式;
public class Singleton2 {private static Singleton2 instance;private Singleton2() {}public static synchronized Singleton2 getInstance() {if (instance == null) {instance = new Singleton2();}return instance;}public static void main(String[] args) {Singleton2 s1 = Singleton2.getInstance();Singleton2 s2 = Singleton2.getInstance();Singleton2 s3 = Singleton2.getInstance();System.out.println(s1.hashCode());System.out.println(s2.hashCode());System.out.println(s3.hashCode());}
}
3.双重校验锁的方式实现单例模式
package 并发的例子.单例模式;
public class Singleton3 {private static volatile Singleton3 instance;private Singleton3() {}public static Singleton3 getInstance() {if (instance == null) {synchronized (Singleton3.class) {if (instance == null) {instance = new Singleton3();}}}return instance;}
}
4.静态内部类方式实现单例模式【推荐】
package 并发的例子.单例模式;
public class Singleton4 {private Singleton4() {}private static class SingletonHolder {private static final Singleton4 INSTANCE = new Singleton4();}public static Singleton4 getInstance() {return SingletonHolder.INSTANCE;}public static void main(String[] args) {Singleton4 s1 = Singleton4.getInstance();Singleton4 s2 = Singleton4.getInstance();Singleton4 s3 = Singleton4.getInstance();System.out.println(s1.hashCode());System.out.println(s2.hashCode());System.out.println(s3.hashCode());}
}
1.为什么用静态内部类?
静态内部类 SingletonHolder 是 “懒汉”:外部类 Singleton4 加载时,它不会跟着加载,真正调用 getInstance() 时才会加载,实现 “用的时候再创建”(懒加载)。
2.线程安全怎么保证?
JVM 加载类时,会保证 “同一类全局只加载一次”,且加载过程是线程安全的(多线程同时调用 getInstance(),SingletonHolder 也只会加载一次)。
因此 INSTANCE 只会创建一次,天然线程安全。
3.对比其他单例的优势
比 “饿汉式” 懒:饿汉式类加载时就创建实例,静态内部类做到了 “用的时候才创建”。
比 “懒汉式(同步方法)” 高效:无需手动加锁,依托 JVM 类加载机制保证线程安全,性能更好。
4.适合场景
需要 懒加载(延迟初始化),且希望 线程安全、代码简洁 的场景。
推荐作为日常开发中 “单例模式” 的首选方案,兼顾性能和安全性。