【设计模式 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(); } }
其余代码与使用单例的相同
打印结果:
分析:额,不用说了吧,结果很明显
三、总结
要把学过的东西,切实的用起来。只是我在想,有那么容易并发吗?我之所以有那种感觉要用上单例,是因为我觉得代理类以及被创建了很多个了,实在没必要再整一堆的真实类对象出来,因为只要有一个,就可以解决问题了!对象多了,占地方!而且,老回收回收,会累的!
额,也有可能是我真的想多了,视情况而定吧。我个人能力有限,要学习的还有很多,还请垂阅本篇博客的人,给予指点!