源自: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线程会同时对这些方法进行访问。

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

FutureResult的getResultValue方法声明如下

public synchronized Object getResultValue(){

while(!this.completed){

try{

this.wait();

}catch(Throwable t){}

}

Java多线程异步调度程序分析(二)的更多相关文章

  1. Java 多线程异步处理demo

    java中实现多线程 1)继承Thread,重写里面的run方法 2)实现runnable接口通过源码发现:第一种方法说是继承Tread然后重写run方法,通过查看run方法的源码,发现run方法里面 ...

  2. “全栈2019”Java多线程第三十二章:显式锁Lock等待唤醒机制详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. Java 多线程基础(十二)生产者与消费者

    Java 多线程基础(十二)生产者与消费者 一.生产者与消费者模型 生产者与消费者问题是个非常典型的多线程问题,涉及到的对象包括“生产者”.“消费者”.“仓库”和“产品”.他们之间的关系如下: ①.生 ...

  4. Java 多线程:锁(二)

    Java 多线程:锁(二) 作者:Grey 原文地址: 博客园:Java 多线程:锁(二) CSDN:Java 多线程:锁(二) AtomicLong VS LongAddr VS Synchroni ...

  5. Java多线程基础知识(二)

    一. Java线程具有6种状态  NEW 初始状态,线程被创建,但是还没有调用start方法. RUNNABLE 运行状态,java线程将操作系统中的就绪和运行两种状态笼统的称作进行中. BLOCKE ...

  6. Java多线程编程——进阶篇二

    一.线程的交互 a.线程交互的基础知识 线程交互知识点需要从java.lang.Object的类的三个方法来学习:    void notify()           唤醒在此对象监视器上等待的单个 ...

  7. 多线程系列之 java多线程的个人理解(二)

    前言:上一篇多线程系列之 java多线程的个人理解(一) 讲到了线程.进程.多线程的基本概念,以及多线程在java中的基本实现方式,本篇主要接着上一篇继续讲述多线程在实际项目中的应用以及遇到的诸多问题 ...

  8. (转载)Java多线程的监控分析工具(VisualVM)

    原文链接:http://blog.csdn.net/chendc201/article/details/22905511 在Java多线程程序运行时,多数情况下我们不知道到底发生了什么,只有出了错误的 ...

  9. Java多线程干货系列—(二)synchronized

    原文地址:http://tengj.top/2016/05/03/threadsynchronized2/ <h1 id="前言"><a href="# ...

随机推荐

  1. linux重新增加硬盘容量

    1.先用df -h查看硬盘使用情况 2.fdisk -l查看分区情况 表示还没有挂载 3.fdisk /dev/vdb进行分区 4.mkfs.ext3 /dev/vdb进行格式化 5.mount /d ...

  2. 【转】.NET开发人员的瓶颈和职业发展

    现在社会比前几年浮躁了,越来越多的人抱怨薪水低,高薪工作不好找; 诚然这有CPI的压力,可是也有很多人没有认清自己的职业发展. 很多.NET程序员个各种纠结,想拿高薪又拿不到,想提高又不知道怎么能提高 ...

  3. 转:PHP – Best Practises

    原文来自于:http://thisinterestsme.com/php-best-practises/ There are a number of good practises that you s ...

  4. Web应用的组件化(一)

    基本思路 1. 为什么要做组件化? 无论前端也好,后端也好,都是整个软件体系的一部分.软件产品也是产品,它的研发过程也必然是有其目的.绝大多数软件产品是追逐利润的,在产品目标确定的情况下,成本有两个途 ...

  5. Linux技术修复

    今天在慕课网上学习了Linux的一些知识: 我使用命令: ***:~$ route add default gw 192.168.1.1 添加了一个网关:192.168.1.1之后的结果为: ***: ...

  6. python学习之---生成器

    通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含1000万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元 ...

  7. 修改 Analysis Service 服务器模式

    原网址:http://cathydumas.com/2012/04/23/changing-an-analysis-services-instance-to-tabular-mode/ Say you ...

  8. 【网络流24题】 No.5 圆桌问题 (多重匹配)

    [题意] 假设有来自 n 个不同单位的代表参加一次国 际会议.每个单位的代表数分别为r i ni , = 1,2, .会议餐厅共有 m 张餐桌,每张餐桌可容纳 ci (i = 1,2, , m) 个 ...

  9. 李洪强iOS开发Swift篇—06_流程控制

    李洪强iOS开发Swift篇—06_流程控制 一.swift中的流程控制 Swift支持的流程结构如下: 循环结构:for.for-in.while.do-while 选择结构:if.switch 注 ...

  10. 不重复查询mysql

    select EquipmentSID,MIN(MatureTime),MIN(ISlock) from table group by name String sql =” Select * from ...