黑马程序员_单例设计模式&多线程

------------ Android培训java培训、期待与您交流!------------
        很多时候我们需要内存中只存在一个类的一个对象,即对象的唯一性。比如,当多线程运行时,需要读取某个文件的内容进行加载并运行,如果这个文件对象不唯一,有可能会重复加载某个类或者功能,造成多条代码执行共享数据(其实这个文件对象就是共享数据了)的线程安全问题,使程序发生错误,这样的情况使我们只想要一个文件对象即可。于是我们就有了单例设计模式。其解决的问题便是 保证一个类在内存中的对象唯一性。
        需要对象的唯一性,解决 思路
                1、不能随便让其他程序或是类创建本类对象;
                2、可以在本类中创建一个对象,并创建一个对外提供对象的方法,以便让其他程序获得此唯一对象。
步骤:
                1、私有化构造函数,那其他程序便不能创建本类对象;
                2、在本类中创建一个对象,为保证唯一,私有并静态;
                3、创建一个公共的返回本类对象的静态方法。
        
        于是有两种形式可以满足:
饿汉式:
class Single{ 
       private Single(){} 		//私有化构造函数。 
       private static Single s = new Single(); 	//创建私有并静态的本类对象。
       public static Single getInstance(){ 	//定义公有并静态的方法,返回该对象。 
            return s; 
       } 
} 


懒汉式:(也称延迟加载形式) 

 Class Single2{ 
		 	private Single2(){} 
		 	private static Single2 s = null; 
		 	public static Single2 getInstance(){ 
		 			if(s==null) 
		 					s = new Single2(); 
		 			return s; 
		 	}
	}


       
        饿汉式一口气将对象创建并私有,在公共方法中该对象返回即可。
        懒汉式在对象被需要时,才被创建。

当单例设计模式加入多线程技术时,再看两种模式有什么不同呢?
        饿汉式:执行返回对象时,只有一条代码,没有多条代码执行共享数据,不会产生线程安全问题。
        懒汉式:
 Class Single2{ 
		 	private Single2(){} 
		 	private static Single2 s = null; 
		 	public static Single2 getInstance(){ 
		 			if(s==null) //当线程0进入此处时,cpu切换到另外另外的线程1,则就会产生不只一个对象。问题便产生了
		 					s = new Single2(); 
		 			return s; 
		 	}
	}

        经过以上的分析,我们知道懒汉式是会产生线程安全问题的,因而,需要进行同步加锁。


        
class Single2{
	private static Single2 s = null;
	private Single2(){}
	public static synchronized Single2 getInstance(){
		if (s == null){	
			s = new Single2();	
		}
		return s;
	}
}
        经过上面的同步,便可解决线程安全问题,但还有些小瑕疵。当多线程执行时,不管是否对象已经创建,每条线程都要判断同步锁,会造成效率的降低。是否还有办法呢?试试换成同步代码块的形式。
class Single2{
	private static Single2 s = null;
	private Single2(){}
	public static Single2 getInstance(){
		synchronized(Single2.class){
			if (s == null){
				s = new Single2();
				
			}
		}
		return s;
	}
}
        问题依然,每次还是都要判断同步锁。但我们知道,只要创建了对象,其他线程便不能再创建,因而,可以把对象是否为null的条件,做提前判断。
class Single{
	private static Single s = null;
	private Single(){}
	public static Single getInstance(){
		if (s == null){	//此判断为提高效率。
			synchronized(Single.class){
				if (s == null){
					s = new Single();
				}
			}
		}
		return s;
	}
}
        这样便能解决效率问题,同步也解决了线程安全问题。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值