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; }
如有问题或建议,请留言,我会尽快完善的,感激不尽
下载代码:)