转载

单例设计模式-(你确定自己写的懒汉单例真的是线程安全的吗)

1、单例设计模式的优缺点

优点:

1):只创建一个实例,就可以到处使用,加快创建实体的效率

缺点:

1):如果使用的频率比较低,实例会一直占据着内存空间,会造成资源浪费

2):可能会出现线程安全问题

2、单例设计模式的两种定法(饿汉、懒汉)

饿汉方法写法:( 可能会造成资源浪费,类一被加载就创建了实例,但并不能确保这个实例什么时候会被用上

package com.zluo.pattern;  /**  *   * 项目名称:single-instance <br>   * 类名称:SingleInstance_01  <br>  * 类描述: 饿汉型写法<br>  * 创建人:louzhangjie  <br>  * 创建时间:2015年5月23日 下午1:55:53  <br>  * 修改人:louzhangjie <br>  * 修改时间:2015年5月23日 下午1:55:53  <br>  * 修改备注:  <br>  * @version 1.0  <br>  *  */ public class SingleInstance_01 {      private static SingleInstance_01 instance = new SingleInstance_01();          private SingleInstance_01(){              }          public static SingleInstance_01 getInstance(){         return instance;     } }

对于饿汉写法而言,它并不会出现线程安全问题,而对于懒汉写法在多线程的情况下就可能会造成线程安全问题,主要是因为在创建实例的时候,可能会创建出多个实例

一般写法:(下面的写法看似没有问题,但它真的已经线程安全了吗?)

public static SingleInstance_02 getInstanceWithThreadSafe(){  try{    if(instance == null){
//A Thread.sleep(
1000); synchronized ("") { instance = new SingleInstance_02(); } } return instance; }catch(Exception e){ e.printStackTrace(); return null; } }

(实际上,上面写法依然还会出现线程安全问题,因为当有两个线程进入到了A当中,即使在创建实体类的时候加上了锁,但依然还是会创建多个实例出来,前一个线程所创建的实例对已经进入到A的线程没有产生任何影响,这也是这种写法的一个漏洞吧)

优化后的写法:

public static SingleInstance_02 getInstanceWithOutThreadSafe(){  try{   if(instance == null){    //假设有线程1、线程2在此等待    Thread.sleep(1000);    synchronized ("") {     if(instance == null){      //再加一次是否为空判断就是为了防出现有多个线在等待锁的情况      instance = new SingleInstance_02();     }    }   }  }catch(Exception e){   e.printStackTrace();  }  return instance; } 

如有问题或建议,请留言,我会尽快完善的,感激不尽

下载代码:)

正文到此结束
Loading...