Active Objects设计模式

   Active是主动的意思,Active Object是主动对象的意思。主动对象就是拥有自己的独立线程。 Active Object模式不仅有自己的独立线程,还可以接受异步消息,并能返回处理结果。从标准的Active Objects设计入手,将一个接口的方法调用转换成可接收异步消息的主动对象,也就是说方法的执行和方法的调用是在不同的线程中进行的,接口方法的参数以及具体的实现封装成特定的Message告诉执行线程,接口方法需要返回值,必须以Future形式返回。

   第一种方法:当某个线程调用OrderService接口的findOrderDetails方法时,是会发送一个包含findOrderDetails方法参数以及OrderService具体实现的Message到Message队列,执行线程通过从队列中获取Message来调用具体的实现,接口的方法的调用和接口方法的执行分别处于不同的线程中,因此称该接口为Active Objects(可接受异步消息的主动对象)。 具体样例代码如下:

public interface OrderService {
Future<String> findOrderDetails(long orderId);
void order(String account,long orderId);
}
public class OrderServiceImpl implements OrderService{
@Override
public Future<String> findOrderDetails(long orderId) {
return FutureService.<Long,String>newService().submit(input->{
try {
System.out.println("process the orderId->"+orderId);
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "The order details Information";
},orderId);
}@Override
public void order(String account, long orderId) {
try {
System.out.println("process the orderId->"+orderId+" , account->"+account);
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
public class OrderServiceProxy implements OrderService{
private final OrderService orderService;
private final ActiveMessageQueue activeMessageQueue;public OrderServiceProxy(OrderService orderService,ActiveMessageQueue activeMessageQueue) {
this.orderService=orderService;
this.activeMessageQueue=activeMessageQueue;
}@Override
public Future<String> findOrderDetails(long orderId) {
final ActiveFuture<String> activeFuture=new ActiveFuture<>();
Map<String,Object> params=new HashMap<>();
params.put("orderId", orderId);
params.put("activeFuture", activeFuture);
MethodMessage message=new FindOrderDetailsMessage(params,orderService);
activeMessageQueue.offer(message);
return activeFuture;
}@Override
public void order(String account, long orderId) {
Map<String,Object> params=new HashMap<>();
params.put("account", account);
params.put("orderId", orderId);
MethodMessage message=new OrderMessage(params,orderService);
System.out.println("processing in OrderServicePoxy.order method");
activeMessageQueue.offer(message);
}}
public class ActiveFuture<T> extends FutureTask<T>{
@Override
public void finish(T result) {
super.finish(result);
}
}
import java.util.Map;public abstract class MethodMessage {
protected final Map<String,Object> params;
protected final OrderService orderService;public MethodMessage(Map<String,Object> params,OrderService orderService) {
this.params=params;
this.orderService=orderService;
}public abstract void execute();
}
public class FindOrderDetailsMessage extends MethodMessage{public FindOrderDetailsMessage(Map<String, Object> params, OrderService orderService) {
super(params, orderService);
}@Override
public void execute() {
Future<String> realFuture=orderService.findOrderDetails((Long) params.get("orderId"));
ActiveFuture<String> activeFuture=(ActiveFuture<String>)params.get("activeFuture");
try {
String result=realFuture.get();
activeFuture.finish(result);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
import java.util.Map;public class OrderMessage extends MethodMessage{public OrderMessage(Map<String, Object> params, OrderService orderService) {
super(params, orderService);
}@Override
public void execute() {
String account=(String)params.get("account");
long orderId=(long)params.get("orderId");
orderService.order(account, orderId);
}}
import java.util.LinkedList;public class ActiveMessageQueue {
private final LinkedList<MethodMessage> message=new LinkedList<>();public ActiveMessageQueue() {
System.out.println("active Object Thread is build");
new ActiveDaemonThread(this).start();
}public void offer(MethodMessage methodMessage) {
synchronized(this) {
message.add(methodMessage);
System.out.println("processing in ActiveMessageQueue.offer method");
this.notify();
}
}protected MethodMessage take() {
synchronized(this) {
while(message.isEmpty()) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("processing in ActiveMessageQueue.take method");
return message.removeFirst();
}
}
}
public class ActiveDaemonThread extends Thread{
private final ActiveMessageQueue queue;public ActiveDaemonThread(ActiveMessageQueue queue) {
super("ActiveDaemonThread");
this.queue=queue;
this.setDaemon(true);
}@Override
public void run() {
for(;;) {
System.out.println(" active daemon thread is running");
MethodMessage methodMessage=this.queue.take();
methodMessage.execute();
}
}}
public class OrderServiceFactory {
private final static ActiveMessageQueue activeMessageQueue=new ActiveMessageQueue();private OrderServiceFactory() {}public static OrderService toActiveObject(OrderService orderService) {
return new OrderServiceProxy(orderService,activeMessageQueue);
}}
public class AOtest {public static void main(String[] args) {
OrderService orderService=OrderServiceFactory.toActiveObject(new OrderServiceImpl());
orderService.order("aACC", 5);
Future<String> f=orderService.findOrderDetails(50);
try {
System.out.println("future result is "+f.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Return immedately");
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}

    第二种方法:第一种方法在接口方法非常多的情况下,会需要封装成很多的Message类。基于JDK动态代理的方式,可以实现一种更加通用的Active Objects。这种方式下,可以将任意接口方法转换w Active Objects,如果接口方法有返回值,必须返回Future类型才可以,否则会抛出IllegalActiveMethod异常。示例代码如下:

public class IllegalActivedException extends Exception{
public IllegalActivedException(String message) {
super(message);
}
}
public interface OrderService {
Future<String> findOrderDetails(long orderId);
void order(String account,long orderId);
}
public class OrderServiceImpl implements OrderService{@ActiveMethod
@Override
public Future<String> findOrderDetails(long orderId) {
return FutureService.<Long,String>newService().submit(input->{
try {
System.out.println("process the orderId->"+orderId);
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "The order details Information";
},orderId);
}@ActiveMethod
@Override
public void order(String account, long orderId) {
try {
System.out.println("process the orderId->"+orderId+" , account->"+account);
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;import java.lang.annotation.Retention;
import java.lang.annotation.Target;@Retention(RUNTIME)
@Target(METHOD)
public @interface ActiveMethod {}
public class ActiveMessage {
private final Object[] objects;
private final Method method;
private final ActiveFuture<Object> future;
private final Object service;private ActiveMessage(Builder builder) {
this.objects=builder.objects;
this.method=builder.method;
this.future=builder.future;
this.service=builder.service;
}public void execute() {
Object result;
try {
result = method.invoke(service, objects);
if(future!=null) {
Future<?> realFuture= (Future<?>)result;
Object realResult=realFuture.get();
future.finish(realResult);
}
} catch (Exception e) {
if(future!=null) {
future.finish(null);
}
e.printStackTrace();
}
}static class Builder{
private Object[] objects;
private Method method;
private ActiveFuture<Object> future;
private Object service;public Builder useMethod(Method method) {
this.method=method;
return this;
}public Builder returnFuture(ActiveFuture<Object> future) {
this.future=future;
return this;
}public Builder withObjects(Object[] objects) {
this.objects=objects;
return this;
}public Builder forService(Object service) {
this.service=service;
return this;
}public ActiveMessage build() {
return new ActiveMessage(this);
}}}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;import org.multithread.future.Future;public class ActiveServiceFactory {
private final static ActiveMessageQueue queue=new ActiveMessageQueue();public static <T> T active(T instance) {
Object proxy=Proxy.newProxyInstance(instance.getClass().getClassLoader(),
instance.getClass().getInterfaces(),
new ActiveInvocationHandler<>(instance));
return (T)proxy;
}private static class ActiveInvocationHandler<T> implements InvocationHandler{
private final T instance;ActiveInvocationHandler(T instance){
this.instance=instance;
}private void checkMethod(Method method) throws IllegalActivedException{
if(!isReturnVoidType(method)&&!isReturnFutureType(method)) {
throw new IllegalActivedException("the method ["+method.getName()+"] return type must be void/Future");
}
}private boolean isReturnVoidType(Method method) {
return method.getReturnType().equals(Void.TYPE);
}private boolean isReturnFutureType(Method method) {
return method.getReturnType().isAssignableFrom(Future.class);
}@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.isAnnotationPresent(ActiveMethod.class)) {
this.checkMethod(method);
ActiveMessage.Builder builder=new ActiveMessage.Builder();
builder.useMethod(method).withObjects(args).forService(instance);
Object result=null;
if(this.isReturnFutureType(method)) {
result=new ActiveFuture<>();
builder.returnFuture((ActiveFuture) result);
}
queue.offer(builder.build());
return result;
}else {
return method.invoke(instance, args);
}
}}}
import java.util.LinkedList;public class ActiveMessageQueue {
private final LinkedList<ActiveMessage> activeMessages=new LinkedList<>();public ActiveMessageQueue() {
System.out.println("active Object Thread is build");
new ActiveDaemonThread(this).start();
}public void offer(ActiveMessage activeMessage) {
synchronized(this) {
this.activeMessages.add(activeMessage);
System.out.println("processing in ActiveMessageQueue.offer method");
this.notify();
}
}public ActiveMessage takeActive() {
synchronized(this) {
while(this.activeMessages.isEmpty()) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return this.activeMessages.removeFirst();
}
}}
public class ActiveDaemonThread extends Thread{
private final ActiveMessageQueue queue;public ActiveDaemonThread(ActiveMessageQueue queue) {
super("ActiveDaemonThread");
this.queue=queue;
this.setDaemon(true);
}@Override
public void run() {
for(;;) {
System.out.println(" active daemon thread is running");
ActiveMessage activeMessage=this.queue.takeActive();
activeMessage.execute();
}
}
}
public class AOtest {public static void main(String[] args) {
ActiveServiceFactory activeInstance=new ActiveServiceFactory();
OrderService orderService=activeInstance.active(new OrderServiceImpl());
orderService.order("aACC", 5);
Future<String> f=orderService.findOrderDetails(150);
try {
System.out.println("future result is "+f.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Return immedately");
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/220163.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apache Flink(十三):Flink History Server

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录

《系统架构设计师教程(第2版)》第2章-计算机系统基础知识-06-系统工程

文章目录 1 系统工程概述2. 系统工程方法2.1 霍尔的三维结构2.2 切克兰德方法2.3 并行工程法2.4 综合集成法2.5 WSR系统方法3. 系统工程的生命周期3.1 各阶段1)探索性研究阶段2)概念阶段3)开发阶段4)生产阶段5)使用阶段6)保障阶段7)退役阶段3.2 生命周期方法1)计划驱动方…

缺钱走投无路怎么办

应对财务困境的有效方式 1. 审视并制定财务计划 评估个人或家庭的财务状况&#xff0c;分析收入和支出。制定财务预算&#xff0c;优先支付必要的支出&#xff0c;例如食品、住房和基本生活费用。 2. 与信用机构或服务提供商协商 如果无法按时支付账单或贷款&#xff0c;请…

区块链的可拓展性研究【05】闪电网络

1.闪电网络&#xff1a;闪电网络是一种基于比特币区块链的 Layer2 扩容方案&#xff0c;它通过建立一个双向支付通道网络&#xff0c;实现了快速、低成本的小额支付。闪电网络的交易速度非常快&#xff0c;可以达到每秒数万笔交易&#xff0c;而且交易费用非常低&#xff0c;几…

Spring中的经典的9种设计模式

Spring中的经典的9种设计模式 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在编写高质量、可维护的代码时&#xff0c;设计模式是我们的得力工具之一。今天&#xff0c;让我们一同探讨Spring中的经典…

04.仿简道云公式函数实战-QLExpress基础语法

1. 前言 小伙伴大家好&#xff0c;在上一篇文章我们简单初探了QLExpress表达式引擎&#xff0c;我们简单写了一个HelloWorld的程序&#xff0c;并成功的运行期望的结果。在本篇文章中我们来熟悉一下QLExpress的语法&#xff0c;因为我们在后面简道云公式实战的时候&#xff0c…

发布 Whatsonchain 上的 BSV20 插件

我们发布了 whatsonchain 上的 BSV20 插件来验证 BSV20 代币。 对于任何交易&#xff0c;whatsonchain 都可以通过以下网址打开&#xff1a; https://whatsonchain.com/tx/{hash}我们使用此 bsv20 v21 交易 打开 Whatsonchain 。 打开whatsonchain后你会看到BSV20插件&#x…

Linux系统安装MySQL8.0版本详细教程【亲测有效】

首先官网下载安装包&#xff1a;https://downloads.mysql.com/archives/community/ 一、上传到安装服务器 二、解压 tar -xvf mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz三、移动位置并重新命名 mv mysql-8.0.31-linux-glibc2.12-x86_64 /usr/local/mysql四、创建mysql用户…

解密布隆过滤器:数据领域的魔法阵

解密布隆过滤器&#xff1a;数据领域的魔法阵 前言布隆过滤器简介基本概念&#xff1a;核心原理&#xff1a;工作方式&#xff1a;注意事项&#xff1a; 设计原理数据结构&#xff1a;哈希函数&#xff1a;高效查找原理&#xff1a; 误判率和容量的权衡误判率问题&#xff1a;容…

官宣 | HelpLook已入驻企业微信应用市场

HelpLook正式入驻企业微信第三方应用市场。 HelpLook支持自定义域名与AI站内搜索&#xff0c;能够帮助企业微信用户搭建所见即所得的企业知识库、产品帮助中心、用户手册、企业博客。 | 怎么找到HelpLook并开始使用 在企业微信的第三方应用就可直接搜索HelpLook&#xff0c;添…

虚幻学习笔记14—重叠和碰撞事件

一、前言 在开发应用当中两个物体的重叠和碰撞事件会经常用到&#xff0c;在虚幻中哲两个有很大的区别&#xff0c;在官方文档碰撞概述其实已经讲了怎样发生碰撞和重叠&#xff0c;但是还是遗漏不少注意事项合细节&#xff0c;主要文档写的太粗糙了&#xff0c;这也让我在使用的…

C++Weekly - Code Review: O3DE Game Engine

对宣布开源的3D游戏引擎O3DE的简单Code Review。 A Quick Look At the Source To Amazons O3DE Game Engine. (Open source 3D Engine) 之前叫做Lumberyard。 Home - O3DE 1&#xff0c;pull up the code on github&#xff0c;用的是CLion 2&#xff0c;先查看CMake。用的…

docker---数据卷

docker---数据卷 数据卷: 容器与宿主机之间进行数据共享 数据卷是一个供容器使用的特殊的目录&#xff0c;容器的目录和宿主机的目录进行映射&#xff0c;主机和宿主机之间都可以对目录中的文件进行修改&#xff0c;双发同步生效。对镜像也没有影响。宿主机到容器实现数据迁移…

区块链是个啥

区块链算是一个散尽硝烟的热点&#xff0c; 现在说这个&#xff0c;有点冷水里冒热气的感觉。 先百度一下&#xff0c;区块链就是一个又一个区块组成的链条。每一个区块中保存了一定的信息&#xff0c;它们按照各自产生的时间顺序连接成链条。这个链条被保存在所有的服务器中..…

Docker Compose入门:打造多容器应用的完美舞台

Docker Compose 是一个强大的工具&#xff0c;它允许开发者通过简单的 YAML 文件定义和管理多容器的应用。本文将深入讨论 Docker Compose 的基本概念、常用命令以及高级应用场景&#xff0c;并通过更为丰富和实际的示例代码&#xff0c;助您轻松掌握如何通过 Docker Compose 打…

【08】ES6:运算符的扩展

一、指数运算符 指数运算符&#xff08;**&#xff09;返回第一个操作数取第二个操作数的幂的结果。 x ** y2 ** 2 // 4 2 ** 3 // 8指数运算符是右结合的。 a ** b ** c 等于 a ** (b ** c)2 ** 3 ** 2 // 相当于 2 ** (3 ** 2) 512指数运算符可以与等号结合&#xff0c;…

数据结构和算法 - 前置扫盲

数据结构和算法 一、前置扫盲 1、数据结构分类 1.1 逻辑结构&#xff1a;线性与非线性 tip&#xff1a;逻辑结构揭示了数据元素之间的逻辑关系。 线性数据结构&#xff1a;元素间存在明确的顺序关系。 数据按照一定顺序排列&#xff0c;其中元素之间存在一个对应关系&#x…

独立完成软件的功能的测试(5. 完结总结)

独立完成软件的功能的测试&#xff08;5. 完结&总结&#xff09; 软件测试的基础理论 1. 什么是软件&#xff1a;控制计算机硬件的工具。2. 什么是软件测试&#xff1a;使用技术的手段&#xff0c;查找软件的缺陷&#xff0c;保证软件的质量3. 软件测试的分类1. 阶段分&am…

Liunx系统挂载磁盘

1.具体步骤 大概五个步骤 添加磁盘磁盘分区格式化分区挂载分区到指定目录设置开机自动挂载 目标将sdb1分区挂载到/data目录 2.添加磁盘 使用lsblk -f命令可以查看当前系统磁盘情况 lsblk -f 可以看到已经有一个磁盘sda&#xff0c;现在我们给虚拟机增加一个磁盘 添加完成后…

数据结构-集合

介绍 数据结构中的集合是一种包含不同元素的数据结构&#xff0c;其中每个元素都是独一无二的&#xff0c;即集合中的元素互不相同且无序。 集合数据结构分类如下&#xff1a; 并集是两个集合的所有部分合并在一起形成的集合&#xff1b;交集是两个集合共同包含的元素组成的集…