java多线程之Active Object模式

23 篇文章 0 订阅
20 篇文章 0 订阅

一、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.示例程序的类图

img

3.示例程序时序图

img

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<String> 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<String> 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<String> makeString(int count, char fillchar) {
        FutureResult<String> future = new FutureResult<String>();
        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<T> {
    protected final Servant servant;
    protected final FutureResult<T> future;

    protected MethodRequest(Servant servant, FutureResult<T> 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<String> {
    private final int count;
    private final char fillchar;

    public MakeStringRequest(Servant servant, FutureResult<String> future, int count, char fillchar) {
        super(servant, future);
        this.count = count;
        this.fillchar = fillchar;
    }

    public void execute() {
        Result<String> 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<Object> {
    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<T> {
    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<T> extends Result<T> {
    private Result<T> result;
    private boolean ready = false;

    public synchronized void setResult(Result<T> 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<T> extends Result<T> {
    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<String> 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<String>(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模式的类图

img

代码案例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值