导读:上篇博客说到,我想将单例模式和代理模式结合起来,以尽可能避免在并发情况下的真实对象的重复创建。光说不练,假把式,代码走你!

一、使用了单例模式的效果

接口:

public interface IDBQuery{
	String Request();
}

实现类:DBQuery

备注:添加构造方法,是为了测试本类被创建的次数

public class DBQuery implements IDBQuery{
	
	private static int i=0;
	public DBQuery(){
		System.out.println("haha");
		i++;
	}
	
	private static class DBQueryHolder{
		private static final DBQuery INSTANCE=new DBQuery();
		private DBQueryHolder(){}
	}
	
	public static final DBQuery getInstance(){
		return DBQueryHolder.INSTANCE;
	}
	@Override
	public String Request(){
		return "request String"+i;
	}
}

代理类:DBQueryProxy

public class DBQueryProxy implements IDBQuery{
	private DBQuery real=null;
	@Override
	public String Request(){
		if(real==null){
			real =DBQuery.getInstance();
		}
		return real.Request();
	}
}
测试类:Main(哈哈,终于用了一把CountDownLatch)

import java.util.concurrent.CountDownLatch;

public class Main {
	private Main() {
	}
	public static void main(String args[]) throws InterruptedException {

		final CountDownLatch beginCountDown = new CountDownLatch(5);// 同步开始信号量
		final CountDownLatch endCountDown = new CountDownLatch(5);// 同步结束信号量
		for (int i = 0; i < 5; i++) {
			new Thread() {
				@Override
				public void run() {
					System.out.println("我是第" + this.getName() + "号线程,我已经准备好了!");
					beginCountDown.countDown();

					try {
						beginCountDown.await();// 等待5个线程准备就绪
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					// 并发内容--------开始---------
					IDBQuery q = new DBQueryProxy();
					System.out.println(q.Request());
					System.out.println("我是第" + this.getName() + "号线程,我已经访问完了!");
					
					// 并发内容--------结束---------
					endCountDown.countDown();// 等待所有线程执行结束,完成一个信号量减一
				}
			}.start();
		}
		try {
			endCountDown.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			System.out.println("并发执行结束");
		}
	}
}

打印结果:



分析:从打印“haha”的次数,以及 i 变量的值来看,真实类DBQuery只被创建了一次


二、不适用单例模式的效果

DBQuery类:

public class DBQuery implements IDBQuery{
	
	private static int i=0;
	public DBQuery(){
		System.out.println("haha");
		i++;
	}
	
	@Override
	public String Request(){
		return "request String"+i;
	}
}
DBQueryProxy代理类:

public class DBQueryProxy implements IDBQuery{
	private DBQuery real=null;
	@Override
	public String Request(){
		if(real==null){
			real =new DBQuery();
		}
		return real.Request();
	}
}

其余代码与使用单例的相同

打印结果:


分析:额,不用说了吧,结果很明显


三、总结

要把学过的东西,切实的用起来。只是我在想,有那么容易并发吗?我之所以有那种感觉要用上单例,是因为我觉得代理类以及被创建了很多个了,实在没必要再整一堆的真实类对象出来,因为只要有一个,就可以解决问题了!对象多了,占地方!而且,老回收回收,会累的!

额,也有可能是我真的想多了,视情况而定吧。我个人能力有限,要学习的还有很多,还请垂阅本篇博客的人,给予指点!

posted on 2017-01-15 21:06  何红霞  阅读(352)  评论(0编辑  收藏  举报