登录
原创

Java单例模式(3)

专栏Java单例
发布于 2020-10-30 阅读 721
  • Java
原创

本文介绍Java单例模式的第三种

这种策略和前两种的区别是,没有使用静态代码块来进行初始化,而是在调用静态方法获取实例的时候来检查实例是否已经被初始化了,如果发现为null,再进行初始化。这应该是一个非常好的方法,因为我们只有在进行需要的时候才把它加载到内存里面。

代码部分

package singleton;

public class Student03 {

  public static Student03 instance;
  private Student03(){

  }


  public static Student03 getInstance() {
      if (instance == null) {
          //try {
          //    Thread.sleep(1);
          //} catch (InterruptedException e) {
          //    e.printStackTrace();
          //}
          instance = new Student03();
      }
      return instance;
  }

  public static void main(String[] args) {
      for (int i = 0; i < 100; i++) {
          new Thread(new Runnable() {
              @Override
              public void run() {
                  System.out.println(Student03.getInstance().hashCode());
              }
          }).start();
      }
  }
}

# 问题分析

运行上面的代码,输出

1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657
1069948657


可以看到启动100个线程去获取实例的时候是没有问题的(也许会有)。那么我们尝试把注释的代码释放出来,再次运行一下,输出如下:

115425294
1324170122
1122783822
305859450
1324170122
305859450
1324170122
833699042
1907757091
115425294
833699042
1409101165
1331751823
1907757091
815626842
815626842
956353159
815626842
815626842
197100096
1324170122
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842
815626842


可以很明显得看到,得到的实例已经不是同一个实例了。这是为什么呢?
假设有两个线程同时运行到了if (instance == null) 这一行,那么,两个线程都可以运行到下面的一行,然后运行instance = new Student03();这一行,那么这个静态变量就会被实例化两次了,那么,如果有更多的线程同时运行到if (instance == null) 这一行的话,就会实例化更多的实例。

评论区

眉上的汗水,眉下的泪水,你总要选择一样

0

0

0

举报