• 【设计模式 6】单例模式和代理模式的结合使用测试


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

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

    接口:

    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();
    	}
    }

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

    打印结果:


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


    三、总结

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

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

  • 相关阅读:
    JSON介绍
    json例子(后台取消息)
    在Struts 2中使用JSON Ajax支持
    JSON介绍
    json例子(后台取消息)
    64位播放器播放RMVB时一卡一顿
    标记一个:HookQQ QQFun CWUB
    Android开发环境搭建全程演示(jdk+eclip+android sdk)
    64位播放器播放RMVB时一卡一顿
    一种可做特殊用途的字符串匹配算法
  • 原文地址:https://www.cnblogs.com/hhx626/p/7534610.html
Copyright © 2020-2023  润新知