java多线程之Active Object模式

java多线程之Active Object模式

一、Active Object模式-接收异步消息的主动对象

Active是主动的意思,因此ActiveObject就是主动对象的意思。所谓主动一般指有自己特有的线程,举例来说,java.lang.Thread类的实例就是一种主动对象。

不过,在Active Object模式中出厂的主动对象可不仅仅有自己特有的线程,它同时还具备可以从外部接收和处理异步消息并根据需要返回处理结果的特征。

Active Object模式中的主动对象会通过自己特有的线程在合适的时机处理从外部接收到的异步消息。

在Active Object中,组成主动对象与许多自然人组成法人类似,即使是java语言这样没有异步消息的编程语言,也可以使用Active Object模式组成实际上能够处理异步消息的主动对象。

二、示例程序

将通过示例程序实现“生成字符串”和“显示字符串”这二种功能的主动对象。

1.示例程序类和接口一览表

类名说明Main.java测试示例程序的类MakerClientThread.java发出“生成字符串”请求的线程DisplayClientThread.java发出“显示字符串”请求的线程ActiveObject.java定义“主动对象”的接口(API)的接口ActiveObjectFactory.java创建“主动对象”的类Proxy.java将方法调用转换为MethodRequest对象的类(实现了ActiveObject的接口)SchedulerThread.java调用execute方法处理 MethodRequest对象的类ActivationQueue.java按顺序保存MethodRequest对象的类MethodRequest.java表示请求的抽象类MakeStringRequest.javamakeString方法(生成字符串)对应的类,MethodRequest类的子类DisplayStringRequest.javadisplayString方法(显示字符串)对应的类,MethodRequest类的子类Result.java表示执行结果的抽象类FutureResult.java在Future模式中表示执行结果的类RealResult.java表示实际的执行结果的类Servant.java执行实际处理的类(实现了ActiveObject接口)

2.示例程序的类图

3.示例程序时序图

4.Main类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:35

* @Description:

*/

public class Main {

public static void main(String[] args) {

ActiveObject activeObject = ActiveObjectFactory.createActiveObject();

new MakerClientThread("Steve Nash", activeObject).start();

new MakerClientThread("Michael Jordan", activeObject).start();

new DisplayClientThread("Ronaldo", activeObject).start();

}

}

5.MakerClientThread类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:35

* @Description:

*/

public class MakerClientThread extends Thread {

private final ActiveObject activeObject;

private final char fillchar;

public MakerClientThread(String name, ActiveObject activeObject) {

super(name);

this.activeObject = activeObject;

this.fillchar = name.charAt(0);

}

public void run() {

try {

for (int i = 0; true; i++) {

//有返回值的调用

Result result = activeObject.makeString(i, fillchar);

Thread.sleep(10);

String value = result.getResultValue();

System.out.println(Thread.currentThread().getName() + ": value = " + value);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

6.DisplayClientThread类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:35

* @Description:

*/

public class DisplayClientThread extends Thread {

private final ActiveObject activeObject;

public DisplayClientThread(String name, ActiveObject activeObject) {

super(name);

this.activeObject = activeObject;

}

public void run() {

try {

for (int i = 0; true; i++) {

//没有返回值的调用

String string = Thread.currentThread().getName() + " " + i;

activeObject.displayString(string);

Thread.sleep(200);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

7.ActiveObject类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:35

* @Description:

*/

public interface ActiveObject {

public abstract Result makeString(int count, char fillchar);

public abstract void displayString(String string);

}

8.ActiveObjectFactory类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:35

* @Description:

*/

public class ActiveObjectFactory {

public static ActiveObject createActiveObject() {

Servant servant = new Servant();

ActivationQueue queue = new ActivationQueue();

SchedulerThread scheduler = new SchedulerThread(queue);

Proxy proxy = new Proxy(scheduler, servant);

scheduler.start();

return proxy;

}

}

9.Proxy类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:35

* @Description:

*/

public class Proxy implements ActiveObject {

private final SchedulerThread scheduler;

private final Servant servant;

public Proxy(SchedulerThread scheduler, Servant servant) {

this.scheduler = scheduler;

this.servant = servant;

}

@Override

public Result makeString(int count, char fillchar) {

FutureResult future = new FutureResult();

scheduler.invoke(new MakeStringRequest(servant, future, count, fillchar));

return future;

}

@Override

public void displayString(String string) {

scheduler.invoke(new DisplayStringRequest(servant, string));

}

}

10.SchedulerThread类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:35

* @Description:

*/

public class SchedulerThread extends Thread {

private final ActivationQueue queue;

public SchedulerThread(ActivationQueue queue) {

this.queue = queue;

}

public void invoke(MethodRequest request) {

queue.putRequest(request);

}

public void run() {

while (true) {

MethodRequest request = queue.takeRequest();

request.execute();

}

}

}

11.ActivationQueue类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:37

* @Description:

*/

public class ActivationQueue {

private static final int MAC_METHOD_REQUEST = 100;

private final MethodRequest[] requestQueue;

private int tail; //下次putRqueset的位置

private int head; //下次takeRequest的位置

private int count; //MethodRequest的数量

public ActivationQueue() {

this.requestQueue = new MethodRequest[MAC_METHOD_REQUEST];

this.head = 0;

this.tail = 0;

this.count = 0;

}

public synchronized void putRequest(MethodRequest request) {

while (count >= requestQueue.length) {

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

requestQueue[tail] = request;

tail = (tail + 1) % requestQueue.length;

count++;

notifyAll();

}

public synchronized MethodRequest takeRequest() {

while (count <= 0) {

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

MethodRequest request = requestQueue[head];

head = (head + 1) % requestQueue.length;

count--;

notifyAll();

return request;

}

}

12.MethodRequest类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:37

* @Description:

*/

abstract class MethodRequest {

protected final Servant servant;

protected final FutureResult future;

protected MethodRequest(Servant servant, FutureResult future) {

this.servant = servant;

this.future = future;

}

public abstract void execute();

}

13.MakeStringRequest类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:38

* @Description:

*/

public class MakeStringRequest extends MethodRequest {

private final int count;

private final char fillchar;

public MakeStringRequest(Servant servant, FutureResult future, int count, char fillchar) {

super(servant, future);

this.count = count;

this.fillchar = fillchar;

}

public void execute() {

Result result = servant.makeString(count, fillchar);

future.setResult(result);

}

}

14.DisplayStringRequest类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:38

* @Description:

*/

public class DisplayStringRequest extends MethodRequest {

private final String string;

public DisplayStringRequest(Servant servant, String string) {

super(servant, null);

this.string = string;

}

public void execute() {

servant.displayString(string);

}

}

15.Result类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:38

* @Description:

*/

public abstract class Result {

public abstract T getResultValue();

}

16.FutureResult类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:38

* @Description:

*/

public class FutureResult extends Result {

private Result result;

private boolean ready = false;

public synchronized void setResult(Result result) {

this.result = result;

this.ready = true;

notifyAll();

}

public synchronized T getResultValue() {

while (!ready) {

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

return result.getResultValue();

}

}

17.RealResult类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:38

* @Description:

*/

public class RealResult extends Result {

private final T resultValue;

public RealResult(T resultValue) {

this.resultValue = resultValue;

}

public T getResultValue() {

return resultValue;

}

}

18.Servant类

package com.viagra.Active_Object_Pattern.Lesson1;

/**

* @Auther: viagra

* @Date: 2019/11/19 20:39

* @Description:

*/

public class Servant implements ActiveObject {

@Override

public Result makeString(int count, char fillchar) {

char[] buffer = new char[count];

for (int i = 0; i < count; i++) {

buffer[i] = fillchar;

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

return new RealResult(new String(buffer));

}

public void displayString(String string) {

try {

System.out.println("displayString: " + string);

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

19.运行示例程序(每次都不一样)

displayString: Ronaldo 0

Steve Nash: value =

Michael Jordan: value =

Steve Nash: value = S

Michael Jordan: value = M

displayString: Ronaldo 1

Steve Nash: value = SS

displayString: Ronaldo 2

Michael Jordan: value = MM

displayString: Ronaldo 3

Steve Nash: value = SSS

displayString: Ronaldo 4

Michael Jordan: value = MMM

displayString: Ronaldo 5

Steve Nash: value = SSSS

displayString: Ronaldo 6

displayString: Ronaldo 7

Michael Jordan: value = MMMM

displayString: Ronaldo 8

displayString: Ronaldo 9

Steve Nash: value = SSSSS

displayString: Ronaldo 10

displayString: Ronaldo 11

Michael Jordan: value = MMMMM

displayString: Ronaldo 12

displayString: Ronaldo 13

Steve Nash: value = SSSSSS

displayString: Ronaldo 14

displayString: Ronaldo 15

displayString: Ronaldo 16

Michael Jordan: value = MMMMMM

displayString: Ronaldo 17

displayString: Ronaldo 18

displayString: Ronaldo 19

Steve Nash: value = SSSSSSS

displayString: Ronaldo 20

displayString: Ronaldo 21

displayString: Ronaldo 22

Michael Jordan: value = MMMMMMM

displayString: Ronaldo 23

displayString: Ronaldo 24

displayString: Ronaldo 25

displayString: Ronaldo 26

Steve Nash: value = SSSSSSSS

displayString: Ronaldo 27

displayString: Ronaldo 28

displayString: Ronaldo 29

displayString: Ronaldo 30

Michael Jordan: value = MMMMMMMM

displayString: Ronaldo 31

displayString: Ronaldo 32

displayString: Ronaldo 33

displayString: Ronaldo 34

Steve Nash: value = SSSSSSSSS

displayString: Ronaldo 35

displayString: Ronaldo 36

displayString: Ronaldo 37

displayString: Ronaldo 38

Michael Jordan: value = MMMMMMMMM

displayString: Ronaldo 39

displayString: Ronaldo 40

displayString: Ronaldo 41

displayString: Ronaldo 42

displayString: Ronaldo 43

Steve Nash: value = SSSSSSSSSS

displayString: Ronaldo 44

displayString: Ronaldo 45

displayString: Ronaldo 46

displayString: Ronaldo 47

Michael Jordan: value = MMMMMMMMMM

displayString: Ronaldo 48

displayString: Ronaldo 49

displayString: Ronaldo 50

三、Active Object模式中角色

1.Client(委托者)

Client角色调用ActiveObject角色的方法来委托处理,在示例程序中是MakerClinetThread类和DisplayClientThread类。

2.ActiveObject(主动对象)

ActiveObject定义了主动对象向Client提供的接口,在示例程序中是ActiveObject接口类。

3.Proxy(代理人)

Proxy负责将方法调用转换为MethodRequest角色的对象。在示例程序中,是Proxy类。

4.Scheduler

Scheduler负责将Proxy角色传递来的MethodRequest传给ActivationQueue角色,在示例程序中,是SchedulerThread类。

5.MethodRequest

是与来自Client角色的请求对应的角色,在示例程序中,是MethodRequest类。

6.ConcreteMethodRequest

ConcreteMethodRequest是使MethodRequest与具体的方法相对应的角色,在示例程序中是MakeStringRequest类和DisplayStringRequest类。

7.Servant(仆人)

Servant负责实际的处理请求,是示例程序中的Servant类。

8.ActivationQueue(主动列队)

ActivationQueue保存MethodRequest角色的类,是示例程序中的ActivationQueue类。

9.VirtualResult(虚拟结果)

VirtualResult与Future、RealResult角色共同构成了Future模式。是示例程序中的Result类。

10.Future(期货)

Future是Client在获取处理结果时实际调用的角色,是示例程序中的FutureResult类。

11.RealResult(真实结果)

RealResult表示处理结果的角色,Servant角色会创建一个RealResult角色作为处理结果,然后调用Future角色的setRealResult方法将其设置到Future角色中。是示例程序中的RealResult类。

12.Active Object模式的类图

代码案例

相关推荐

为什么高铁动车无座和二等座同价?12306回应→
word 中将两个图像合并到一起
365bet体育在线娱乐场

word 中将两个图像合并到一起

📅 10-23 👁️ 4447
计算下DNF改版后千蛛套的输出能力及适用情况
青梅竹马
365365094

青梅竹马

📅 07-09 👁️ 154
茄怎么读
365365094

茄怎么读

📅 10-10 👁️ 2086
炼狱 - 无畏契约WIKI
365BET-官网

炼狱 - 无畏契约WIKI

📅 09-20 👁️ 2820
青梅竹马
365365094

青梅竹马

📅 07-09 👁️ 154
部落冲突:老鸟专属回忆,建筑工人离家出走?而萌新却浑然不知!
世界政区索引
365BET-官网

世界政区索引

📅 08-25 👁️ 5591