zoukankan      html  css  js  c++  java
  • 线程安全的单例模式

    这几天写到一个监听session的功能,其中涉及到了单例模式的线程安全,但是最开始的代码同事说有问题,代码如下:

    1     private static SessionManager instance;
    2 
    3     public static SessionManager getInstance() {
    4         if (instance == null) {
    5             instance = new SessionManager();
    6         }
    7         return instance;
    8     }

    这种单例就是我记得的懒汉单例,这种单例模式是线程不安全的,即:在多线程时,并不能保证这个类只被实例化一次。解决这个问题需要加锁,代码如下:

    1     private static SessionManager instance;
    2 
    3     public static synchronized SessionManager getInstance() {
    4         if (instance == null) {
    5             instance = new SessionManager();
    6         }
    7         return instance;
    8     }

    通过增加synchronized关键字到getInstance()方法中,迫使每个线程在进入方法之前,要先等别的线程离开该方法。也就是说,不会有两个线程可以同时进入这个方法。

    这种方法存在的问题:当设置好instance变量后,就不再需要同步这个方法了,之后每次调用这个方法,同步都是一种浪费。

    所以我们可以在getInstance中进行加锁判断,代码如下:

     1     private static SessionManager instance;
     2 
     3     public static SessionManager getInstance() {
     4         if (instance == null) {
     5             synchronized (SessionManager.class) {
     6                 if (instance == null) {
     7                     instance = new SessionManager();
     8                 }
     9             }
    10         }
    11         return instance;
    12     }

    这种方法据说会因为java的无序写入失效,所以还是建议使用饿汉单例,代码如下:

    1     private static SessionManager instance = new SessionManager();
    2 
    3     public static SessionManager getInstance() {
    4         return instance;
    5     }

    使用这种方法,JVM在加载这个类时会马上创建唯一的单例实例,所以是线程安全的。

  • 相关阅读:
    计算机中如何表示数字-01机器数与真值
    计算机中如何表示数字-06浮点数
    Java基础类型与其二进制表示
    char类型与Unicode的编码
    数组的详细总结
    Java中的instanceof关键字
    java 启动多线程
    elasticsearch7.2 集群搭建 插件安装 和kibana安装
    java读取 properties配置文件的两种方式
    查询mysql 库和表占的大小
  • 原文地址:https://www.cnblogs.com/dsgzxy527/p/3557259.html
Copyright © 2011-2022 走看看