多线程编程模式之Active Object模式

Active Object模式

Active Object介绍

Active Object模式,介绍了一种多线程环境下,多对象之间共同协作完成任务的方法;该模式综合了:Producer-Consumer模式、Thread-Per Message模式、Future 模式、Thread-Specific Storage模式;

Active Object使用场景

  1. 以多线程的内部实现方式,对外提供功能点;
  2. Active Object开启了通往分布式的序幕;

Active Object示例代码

//Future模式里表示结果的类
public abstract class Result<T> {
    public abstract T getResultValue();
}
//真实的结果——包含数据
public class RealResult<T> extends Result<T> {
    private final T resultValue;
    public RealResult(T resultValue){
        this.resultValue=resultValue;
    }
    @Override
    public T getResultValue(){
        return resultValue;
    }
}
//获取真实结果的凭据
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();
    }
    @Override
    public synchronized T getResultValue(){
        while(!ready){
            try{
                wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        return result.getResultValue();
    }
}
//该类对外提供API
public interface ActiveObject {
    Result<String> makeString(int count,char fillChar);
    void displayString(String string);
}
//任务的实际执行者,实现了ActiveObject接口
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<>(new String(buffer));
    }

    @Override
    public void displayString(String string) {
        try{
            System.out.println("displaySting: "+string);
            Thread.sleep(10);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}
//对方法的包装——请求
public 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();
}
//显示字符串的请求
public class DisplayStringRequest extends MethodRequest<Object> {
    private final String string;
    protected DisplayStringRequest(Servant servant,String string) {
        super(servant, null);
        this.string=string;
    }

    @Override
    public void execute() {
        servant.displayString(string);
    }
}
//生成字符串的请求
public class MakeStringRequest extends MethodRequest<String> {
    private final int count;
    private final char fillChar;
    protected MakeStringRequest(Servant servant, FutureResult<String> future,int count,char fillChar) {
        super(servant, future);
        this.count=count;
        this.fillChar=fillChar;
    }

    @Override
    public void execute() {
        Result<String> result=servant.makeString(count,fillChar);
        future.setResult(result);
    }
}
//该类相当于Producer-Consumer中的Channel,负责缓存请求
public class ActivationQueue {
    private static final int MAX_METHOD_REQUEST=100;
    private final MethodRequest[] requestQueue;
    private int tail;
    private int head;
    private int count;
    public ActivationQueue(){
        this.requestQueue=new MethodRequest[MAX_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;
    }
}
//Client看到的ActiveObject,代理类,具体任务由servant执行
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));
    }
}
//方法调用的线程——负责收集请求,然后调用
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();
        }
    }
}
//生成ActiveObject的工厂——注意,生成ActiveObject的时候,也启动了Schedule线程,返回的是代理类
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;
    }
}
//发送显示命令的线程
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();
        }
    }
}
///发送生成命令的线程
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();
        }
    }
}
//启动类——创建两条生成线程,一条显示线程,共享同一个ActiveObject;
public class Tester {
    public static void main(String[] args){
        ActiveObject activeObject=ActiveObjectFactory.createActiveObject();
        new MakerClientThread("Alice",activeObject).start();
        new MakerClientThread("Bobby",activeObject).start();
        new DisplayClientThread("Chris",activeObject).start();
    }
}

整体的思路如下:

在这里插入图片描述

Active Object理解

Client通过Active Object提供的API使用Active Object提供的功能;但是Active Object并不是一个人在战斗;它组合了调用转换、请求管理、请求执行等功能;实现了调用和执行的分离;

这里,Active Object模式不但体现了OOP中的“封装”,还组合多种多线程设计模式,体现出其综合性;

Active Object实现了跨线程的功能实现;相同的思路,通过配合网络及serialization技术,便可以更好滴理解分布式流程;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值