您的位置:首页 > 编程语言 > Java开发

Java多线程异步调度程序分析(二)

2016-03-22 10:52 567 查看
源自:http://blog.sina.com.cn/s/blog_4cc16fc50100c0uh.html

public abstract class Result { //抽象的结果类

public abstract Object getResultValue();

}

class FutureResult extends Result{ //取货凭证类

private Result result;

private boolean completed;

public synchronized void setResult(Result result){ //存放真实的结果

this.result = result;

this.completed = true;

this.notifyAll();

}

public synchronized Object getResultValue(){ //取结果

while(!this.completed){

try{

this.wait();

}catch(Throwable t){}

}

// 调用RealResult类的getResultValue返回真实结果

return this.result.getResultValue();

}

}

class RealResult extends Result{ //表示真实结果的抽象类

private final Object resultValue;

public RealResult(Object resultValue){

this.resultValue = resultValue;

}

public Object getResultValue(){

return this.resultValue;

}

}

现在这个异步消息处理器已经有了模型,这个异步处理器包括如下对象

Servant 忠心做真实的事务

ActivationQueue 将请求缓存起来以便调度

Scheduler 对容器中的请求根据一定原则进行调度执行

Proxy 将特定方法请求转换为特定对象

所有这些都是这个异步处理器的核心部件,既然是核心部件,我们就要进行封装而不能随便让调用者来修改,所以我们用工厂模式来产生处理器Axman对象

public class AxmanFactory {

public static Axman createAxman() {

Servant s = new Servant(); //创建实际处理请求的对象

ActivationQueue queue = new ActivationQueue(); //创建存放请求的队列

Scheduler st = new Scheduler(queue); //创建调度策略对象

Proxy p = new Proxy(st,s); //创建代理对象

st.start(); //启动调度策略线程Scheduler

return p; //返回代理对象

}

}

用两个请求的产生者不停产生请求

public class ResultInvokeThread extends Thread{

// ResultInvokeThread线程发送需要有返回值的请求

private final Axman ao;

private final char c;

public ResultInvokeThread(String name,Axman ao){

this.ao = ao;

this.c = name.charAt(0);

}

public void run(){

try{

int i = 0;

while(true){

//调用Proxy的ruseultTest方法向队列中添加一个请求,返回取货凭证FutureResult

Result result = this.ao.resultTest(i++,c);

Thread.sleep(10); //等待一段时间

String value = (String)result.getResultValue();

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

}

}

catch(Throwable t){}

}

}

public class NoResultInvokeThread extends Thread{

//NoResultInvokeThread发送不需要返回值的请求

private final Axman ao;

public NoResultInvokeThread(String name,Axman ao){

super(name);

this.ao = ao;

}

public void run(){

try{

int i = 0;

while(true){

String s = Thread.currentThread().getName() + i++;

ao.noResultTest(s);

Thread.sleep(20);

}

}

catch(Throwable t){}

}

}

// 调用程序的主类

public class Program {

public static void main(String[] args) {

//创建代理对象,同时启动调度策略线程Scheduler。

Axman ao = AxmanFactory.createAxman();

new ResultInvokeThread("Axman",ao).start(); //启动需要返回值的请求线程

new ResultInvokeThread("Sager",ao).start();

new NoResultInvokeThread("Macke",ao).start();//启动不需要返回值的请求线程

}

}

1. Scheduler线程运行后,从队列ActivationQueue中取出请求,调用不同请求类型相应的execute方法。

如果请求类型为ResultRequest,ResultRequest的execute方法首先调用Servant的resultTest方法,处理请求(请求处理完成后,返回处理结果RealResult对象);然后调用FutureResult的setResult方法存储结果。

ResultRequest的execute方法

public void execute(){

//创建Result对象,获取的是RealResult对象。

Result result = servant.resultTest(this.count,this.c);

this.future.setResult(result); //将RealResult对象存储。

}

Servant的resultTest方法

public Result resultTest(int count,char c){

char[] buf = new char[count];

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

buf[i] = c;

try{

Thread.sleep(100);

}catch(Throwable t){}

}

//调用RealResult的构造方法,返回RealResult对象。

return new RealResult(new String(buf));

}

FutureResult的setResult方法

public synchronized void setResult(Result result){

this.result = result;

this.completed = true;

this.notifyAll();

}

2. ResultInvokeThread线程运行后,调用Proxy的ruseultTest方法。

resultTest方法创建取货凭证对象FutureResult,然后调用scheduler的invoke方法(invoke方法调用ActivationQueue队列的putRequest方法,向队列中添加请求。),然后返回取货凭证对象。

请求线程调用sleep()等待一段时间。

ResultInvokeThread线程继续调用Result的getResultValue对象,读取执行结果。

3. 程序中有两处需要同步

一是读取与存储请求,这涉及到ActivationQueue队列的getRequest方法和putRequest方法。

Scheduler线程、ResultInvokeThread线程、NoResultInvokeThread线程会同时对这些方法进行访问

二是读取与存储结果,这涉及到FutureResult的getResultValue方法与setResult方法。

Scheduler线程、ResultInvokeThread线程、NoResultInvokeThread线程会同时对这些方法进行访问。

[b]每个请求对应一个请求结果,请求A获取的是请求结果A,不会得到请求结果B。[/b]

FutureResult的getResultValue方法声明如下

public synchronized Object getResultValue(){

while(!this.completed){

try{

this.wait();

}catch(Throwable t){}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: