饿汉式

  1. public class Hunger {
  2. private Hunger() {
  3. }
  4. private static Hunger singleton = new Hunger();
  5. public static Hunger getSingleton() {
  6. return singleton;
  7. }
  8. }

懒汉式

  • volatile + double check

    1. public class LazyTwo {
    2. private static volatile LazyTwo singleton = null;
    3. /*
    4. 实例化对象的步骤
    5. 1. memory = allocate() 分配对象的内存空间
    6. 2. ctorInstance() 初始化对象
    7. 3. instance = memory 设置 instance 指向刚刚分配的内存
    8. 当多线程的时候,可能会指令重排
    9. 例如线程A由于指令重排,导致步骤2和3互换,在进行了1、3、2,假设此时还在初始化对象
    10. 此时线程B进来,直接判断 instance 不为 null,就直接返回了 instance
    11. 此时的 instance 指向的内存还没有初始化完毕,如果贸然使用,可能出问题
    12. 所以用 volatile 修饰对象,禁止对象的创建进行指令重排
    13. */
    14. public static LazyTwo getInstance() {
    15. if (singleton == null) {
    16. synchronized (LazyTwo.class) {
    17. if (singleton == null) {
    18. System.out.println("初始化");
    19. singleton = new LazyTwo();
    20. }
    21. }
    22. }
    23. return singleton;
    24. }
    25. }

单例

  1. public class SingleEnum {
  2. private SingleEnum() {
  3. }
  4. private SingleEnum instance;
  5. public static SingleEnum getInstance() {
  6. return Singleton.INSTANCE.getSingleEnum();
  7. }
  8. private enum Singleton {
  9. INSTANCE;
  10. private SingleEnum singleEnum;
  11. // JVM 保证单例
  12. Singleton() {
  13. singleEnum = new SingleEnum();
  14. }
  15. public SingleEnum getSingleEnum() {
  16. return singleEnum;
  17. }
  18. }
  19. }