• 线程安全的单例模式


    这几天写到一个监听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在加载这个类时会马上创建唯一的单例实例,所以是线程安全的。

  • 相关阅读:
    mysql数据库 及 常用 SQL语句
    移动前端—图片压缩上传实践
    使用Nodejs 的http-proxy 模块做代理服务器的尝试
    Ajax请求参数为文件类型
    <iframe>框架标签的使用
    vue2 核心概念
    关于Web前端密码加密是否有意义的总结
    原生js 与 jQuery对比
    word文档操作
    js (ECMAScript) 对数据处理的 方法、属性总结
  • 原文地址:https://www.cnblogs.com/dsgzxy527/p/3557259.html
Copyright © 2020-2023  润新知