一步步学习java并发编程模式之Active Object模式(三)java实现active object
来源:互联网 发布:js格式化时间戳format 编辑:程序博客网 时间:2024/06/05 03:17
现在我们已经知道active object模式的核心思想,也明白了如何自己写一段实现类似效果的java代码。现在我们按照active object模式的角色分工,将第二篇中的例子重新实现下,参考了Active Object并发模式在Java中的应用 这篇博客。在 Active Object 模式中,主要有以下几种类型的参与者:
- 代理 (proxy) :代理是 Active Object 所定义的对于调用者的公共接口。运行时,代理运行在调用者线程的上下文中,负责把调用者的方法调用转换成相应的方法请求 (Method Request),并将其插入相应的 Activation List,最后返回给调用者 Future 对象。代理角色具有以下几个特点:
1.proxy和servant有着相同的接口签名,或者proxy比servant接口更简单好用。这样可以方便调用者无差别的对待proxy和servant,或者更容易使用代理
2.创建client需要的future对象,并快速返回,避免调用者线程长时间等待.客户端可以通过future对象获取实际的运算结果
3.将调用者的方法调用转换成相应的方法请求 (Method Request),将request和servant传给scheduler进行调度执行
4.代理是运行在调用者线程中的,它对原始的耗时服务进行了封装,让客户端无差异的使用代理和真实对象,除了更快.
2.创建client需要的future对象,并快速返回,避免调用者线程长时间等待.客户端可以通过future对象获取实际的运算结果
3.将调用者的方法调用转换成相应的方法请求 (Method Request),将request和servant传给scheduler进行调度执行
4.代理是运行在调用者线程中的,它对原始的耗时服务进行了封装,让客户端无差异的使用代理和真实对象,除了更快.
- 方法请求(method request):方法请求定义了方法执行所需要的上下文信息,诸如调用参数等。
- activation list:负责存储所有由代理创建的,等待执行的方法请求。从运行时来看,Activation List 会被包括调用者线程及其 Active Object 线程并发存取访问,所以,Activation List 实现应当是线程安全的。
- 调度者 (scheduler):调度者运行在 Active Object 线程中,调度者来决定下一个执行的方法请求,而调度策略可以基于很多种标准,比如根据方法请求被插入的顺序 FIFO 或者 LIFO,比如根据方法请求的优先级等等。
- servant::Servant 定义了 Active Object 的行为和状态,它是 Proxy 所定义的接口的事实实现。
- future:调用者调用 Proxy 所定义的方法,获得 Future 对象。调用者可以从该 Future 对象获得方法执行的最终结果。在真实的实现里,Future 对象会保留一个私有的空间,用来存放 Servant 方法执行的结果。
我们现在先编写servant类,这个是整个active object角色中最简单的
package activeobject.aty.servant;import activeobject.aty.result.WeatherResult;//Servant 的实现是纯粹的应用逻辑实现,或者称为商业逻辑实现,没有混合任何的线程同步机制 , 这有利于我们进行应用逻辑的重用,而不需要考虑不同的线程同步机制。public class WeatherServant{ public WeatherResult getWeatherInfo(String city, String day) { try { // 模拟耗时操作,调用该方法的线程,要挂起5s Thread.sleep(5 * 1000); } catch (InterruptedException e) { } WeatherResult result = new WeatherResult(); result.setTemperature(28); result.setWindDirection("西北风"); result.setDampness("74%"); return result; }}
package activeobject.aty.result;// 模拟天气预报的查询结果//今日天气实况:气温:4℃;风向/风力:西北风 1级;湿度:74%;空气质量:中;紫外线强度:最弱public class WeatherResult{ // 气温 private int temperature; // 湿度 private String dampness; // 风向 private String windDirection; public int getTemperature() { return temperature; } public void setTemperature(int temperature) { this.temperature = temperature; } public String getDampness() { return dampness; } public void setDampness(String dampness) { this.dampness = dampness; } public String getWindDirection() { return windDirection; } public void setWindDirection(String windDirection) { this.windDirection = windDirection; } @Override public String toString() { return "WeatherResult [temperature=" + temperature + ", dampness=" + dampness + ", windDirection=" + windDirection + "]"; } }
现在编写methodrequest和future代码
package activeobject.aty.future;import activeobject.aty.result.WeatherResult;// 调用者调用 Proxy 所定义的方法,获得 Futur 对象。调用者可以从该 Future 对象获得方法执行的最终结果。// 在真实的实现里,Future 对象会保留一个私有的空间,用来存放 Servant 方法执行的结果。public class WeatherFuture{ private boolean isDone = false; private WeatherResult result = null; public WeatherResult get() { while (!isDone) { } return result; } public void setDone(boolean isDone) { this.isDone = isDone; } public void setResult(WeatherResult result) { this.result = result; }}
package activeobject.aty.methodrequest;import activeobject.aty.future.WeatherFuture;import activeobject.aty.result.WeatherResult;import activeobject.aty.servant.WeatherServant;// Method Request:方法请求定义了方法执行所需要的上下文信息,诸如调用参数、返回结果和实际的服务等public class WeatherMethodRequest{ private WeatherFuture future; private WeatherServant servant; private String city; private String day; public WeatherMethodRequest(WeatherFuture future, WeatherServant servant, String city, String day) { this.future = future; this.servant = servant; this.city = city; this.day = day; } public void call() { WeatherResult result = servant.getWeatherInfo(city, day); future.setResult(result); future.setDone(true); }}
下面编写activation list
package activeobject.aty.activationlist;import java.util.ArrayList;import java.util.List;import activeobject.aty.methodrequest.WeatherMethodRequest;// Activation List 负责存储所有由代理创建的,等待执行的方法请求。// 从运行时来看,Activation List 会被包括调用者线程及其 Active Object线程并发存取访问,所以Activation List 实现应当是线程安全的.// Activation List 的实际上就是一个线程同步机制保护下的 Method Request队列,对该队列的所有操作 (insert/remove)都应该是线程安全的。// 从本质上讲,Activation List 所基于的就是典型的生产者 / 消费者并发编程模型,调用者线程作为生产者把// Method Request放入该队列,Active Object 线程作为消费者从该队列拿出 Method Request, 并执行。public class WeatherActivationList{ private List<WeatherMethodRequest> requestList = new ArrayList<WeatherMethodRequest>(); public synchronized void insertTask(WeatherMethodRequest request) { requestList.add(request); } public synchronized void removeTask(WeatherMethodRequest request) { requestList.remove(request); } public synchronized boolean isEmpty() { return requestList.size() == 0; } public synchronized WeatherMethodRequest popFirst() { WeatherMethodRequest e = requestList.get(0); requestList.remove(0); return e; }}
到这里我们的请求已经在activation list中了,我们可以基于activation list编写我们的scheduler实现
package activeobject.aty.scheduler;import activeobject.aty.activationlist.WeatherActivationList;import activeobject.aty.methodrequest.WeatherMethodRequest;// Active Object 的线程public class WeatherStartThread implements Runnable{ private WeatherActivationList safeRequestList; public WeatherStartThread(WeatherActivationList safeRequestList) { this.safeRequestList = safeRequestList; } @Override public void run() { while (true) { if (!safeRequestList.isEmpty()) { WeatherMethodRequest request = safeRequestList.popFirst(); request.call(); } } }}
package activeobject.aty.scheduler;import activeobject.aty.activationlist.WeatherActivationList;import activeobject.aty.methodrequest.WeatherMethodRequest;// scheduler:调度者运行在 Active Object线程中,调度者来决定下一个执行的方法请求,// 而调度策略可以基于很多种标准,比如根据方法请求被插入的顺序 FIFO 或者 LIFO,比如根据方法请求的优先级等等。public class WeatherTaskScheduler{ private WeatherActivationList safeRequestList = new WeatherActivationList(); public WeatherTaskScheduler() { new Thread(new WeatherStartThread(safeRequestList)).start(); } public void insertRequest(WeatherMethodRequest methodRequest) { safeRequestList.insertTask(methodRequest); }}
下面我们来编写代理类的实现,这个是客户端直接使用的类
package activeobject.aty.proxy;import activeobject.aty.future.WeatherFuture;import activeobject.aty.methodrequest.WeatherMethodRequest;import activeobject.aty.scheduler.WeatherTaskScheduler;import activeobject.aty.servant.WeatherServant;//代理 (Proxy)负责以下功能:// 1.proxy和servant有着相同的接口签名,或者proxy比servant接口更简单好用。这样可以方便调用者无差别的对待proxy和servant,或者更容易使用代理// 2.创建client需要的future对象,并快速返回,避免调用者线程长时间等待.客户端可以通过future对象获取实际的运算结果// 3.将调用者的方法调用转换成相应的方法请求 (Method Request),将request和servant传给scheduler进行调度执行// 4.代理是运行在调用者线程中的,它对原始的耗时服务进行了封装,让客户端无差异的使用代理和真实对象,除了更快.public class WeatherProxy{ // 对任务进行调度 private static WeatherTaskScheduler scheduler = new WeatherTaskScheduler(); // 服务的真正实现 private static WeatherServant servant = new WeatherServant(); public static WeatherFuture getWeatherInfo(String city, String day) { WeatherFuture futureResult = new WeatherFuture(); WeatherMethodRequest request = new WeatherMethodRequest(futureResult, servant, city, day); scheduler.insertRequest(request); return futureResult; }}
最后我们编写测试类,来验证我们的功能。
package activeobject.aty;import activeobject.aty.future.WeatherFuture;import activeobject.aty.proxy.WeatherProxy;import activeobject.aty.result.WeatherResult;public class TestWeather {public static void main(String[] args) throws Exception {mockMultiCall();testAsyncCall();}public static void testAsyncCall() throws Exception {// 1.调用天气计算服务,开始计算深圳的天气情况(开始计算)WeatherFuture future = WeatherProxy.getWeatherInfo("广东深圳", "2014-03-14");// 2.后台在计算天气服务中.当前线程没有阻塞,仍然可以继续执行.System.out.println("After calling weather service,i am still running.");// 3.The current thread is not blocked, do something else here...// Thread.sleep(5 * 1000);// 4.与天气计算结果无关的代码执行完毕.System.out.println("Now,i really need weather result to continue.");// 5.如果计算天气还没有结束,那么当前线程挂起,等候计算完成.WeatherResult info = future.get();System.out.println("天气查询结果:" + info);}public static void mockMultiCall() {Thread t = new Thread(new Runnable() {@Overridepublic void run() {while (true) {long time = System.currentTimeMillis();System.out.println("构造一个服务调用请求:");WeatherFuture future = WeatherProxy.getWeatherInfo("广东深圳"+ time, "2014-03-14");WeatherResult info = future.get();System.out.println("mockMultiCall结果:" + info);System.out.println();System.out.println();}}});t.start();}}
这样我们就按照active object模式的各个参与者及职责完成了java实现。
1 0
- 一步步学习java并发编程模式之Active Object模式(三)java实现active object
- 一步步学习java并发编程模式之Active Object模式(一)什么是active object
- 一步步学习java并发编程模式之Active Object模式(二)java实现异步调用
- 一步步学习java并发编程模式之Active Object模式(四)改进后的java实现
- 一步步学习java并发编程模式之Active Object模式(五) 使用JDK的内置实现
- java active object 并发模式
- Java多线程编程之Active Object模式
- Java 多线程编程设计模式 Active Object
- java设计模式之Active Object
- Java多线程编程模式实战指南一:Active Object模式
- Java多线程编程模式实战指南(一):Active Object模式
- 任务和主动对象(Active Object):并发编程模式
- java多线程设计模式笔记之Active Object
- [置顶] Java多线程编程模式实战指南(一):Active Object模式(上)
- [置顶] Java多线程编程模式实战指南(一):Active Object模式(下)
- Java多线程编程模式实战指南一:Active Object模式(上)
- Java多线程编程模式实战指南一:Active Object模式(下)
- Active Object模式
- CSS自动竖向排列的布局方法
- 用java模拟银行业务调度系统
- android JIN使用流程
- Python 命令行参数和getopt模块详解
- Spring3.2+hibernate4整合报错 NoSuchMethodError:openSession()解决办法
- 一步步学习java并发编程模式之Active Object模式(三)java实现active object
- zoj 2966 Build The Electric System(并查集)
- RISC与CISC比较
- MVC 三层架构在各框架中的特征
- 通过PostMessage执行按钮事件
- 关于Visual Studio 2013中strcpy函数的使用报错
- Microsoft ADO(ActiveX Data Object)用法浅析
- RMQ with Shifts(线段树单点跟新)
- IT潜力:站在大数据时代