• 单例模式的线程安全问题


    大家都知道单例模式有两种,分别是懒汉式、饿汉式。但是对于饿汉式,由于判断实例为null与创建对象的操作并不是一个原子性操作,故在

    多线程环境下,会存在线程安全问题。

    普通的懒汉式单例(非线程安全问题):

     1 /**
     2  * Created by ywb 
     3  */
     4 public class Singleton {
     5 
     6     private static  Singleton singleton;
     7     private Singleton() {
     8     }
     9 
    10     public static Singleton getInstance() {
    11         if(singleton==null) {
    12             singleton = new Singleton();
    13         }
    14         return singleton;
    15 
    16     }
    17 }

    第11-13行代码是线程不安全的,为解决问题,可以进行如下改变:

    演化版本1:

     1 /**
     2  * Created by ywb 
     3  */
     4 public class Singleton {
     5 
     6     private static  Singleton singleton;
     7     
     8     private Singleton() {
     9     }
    10 
    11     public synchronized static Singleton getInstance() {
    12         if(singleton==null) {
    13             singleton = new Singleton();
    14         }
    15         return singleton;
    16     }
    17 }

    这个版本虽然解决了线程安全问题,但是 synchronized 关键字 却引入了性能问题,可以考虑采用synchronized块缩小同步范围

    演化版本2:

     1 /**
     2  * Created by ywb 
     3  */
     4 public class Singleton {
     5 
     6     private static  Singleton singleton;
     7 
     8     private Singleton() {
     9     }
    10 
    11     public  static Singleton getInstance() {
    12         if(singleton==null) {
    13             synchronized (Singleton.class) {
    14                 singleton = new Singleton();
    15             }
    16         }
    17         return singleton;
    18     }
    19 }

    但是版本2却是存在问题,重新引入了线程安全问题,同步块里可以再次加一个null判断

    演化版本3:

     1 package com.tong.qiu;
     2 
     3 /**
     4  * Created by ywb
     5  */
     6 public class Singleton {
     7 
     8     private static volatile Singleton singleton;
     9 
    10     private Singleton() {
    11     }
    12 
    13     public  static Singleton getInstance() {
    14         if(singleton==null) {
    15             synchronized (Singleton.class) {
    16                 if(singleton==null) {
    17                     singleton = new Singleton();
    18                 }
    19             }
    20         }
    21         return singleton;
    22     }
    23 }

    第8行加入了volatile为了保证内存可见性,本版本最终解决了线程安全问题又兼容考虑了性能问题。

    
    
    
    
    
    
    When things go wrong,don't go with them.
  • 相关阅读:
    Django集成Bootstrap美化后台
    python3 Django集成Ueditor富文本编辑器
    mysql-cluster集群配置
    centos7安装mysql8
    python升级pip和Django安装
    删除某日期之前的日志文件夹
    linux文件系统变为只读解决
    xargs实例
    linux终端提示符显示bash-4.2#
    Codeforces Round #478 (Div. 2)
  • 原文地址:https://www.cnblogs.com/yqy921/p/6275093.html
Copyright © 2020-2023  润新知