首页 > 编程语言 > 详细

单例模式的线程安全问题

时间:2017-01-12 13:02:23      阅读:232      评论:0      收藏:0      [点我收藏+]

大家都知道单例模式有两种,分别是懒汉式、饿汉式。但是对于饿汉式,由于判断实例为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为了保证内存可见性,本版本最终解决了线程安全问题又兼容考虑了性能问题。

 

 



单例模式的线程安全问题

原文:http://www.cnblogs.com/yqy921/p/6275093.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!