多线程程序设计学习(13)Active Object pattern

Active Object[接收异步消息的对象]

一:Active Object的参与者
--->客户端线程(发起某种操作请求处理)
--->代理角色(工头)
--->实际执行者(工人)
--->主动对象接口(工人和工头)
--->生产端线程(加工产品的线程)
--->存放生产请求的队列(存放请求的队列)
--->请求实例化(将方法的启动和执行分离的实例化包含)
--->订单
--->产品
--->订单产品的共同接口
       

二:Active Object模式什么时候使用
--->大型模式,适合处理大并发量的业务场景

三:Active Object思考
--->
四进阶说明        
--->

 

 

Active Object例子
工厂大量需要制造文字

一:订单和产品的接口

 1 package com.yeepay.sxf.thread12;
 2 /**
 3  * 订单和产品的接口
 4  * @author sxf
 5  *
 6  */
 7 public abstract class Result {
 8     //获取结果的方法
 9     public abstract Object getResultValue();
10
11 }

View Code

二:订单类

 1 package com.yeepay.sxf.thread12;
 2 /**
 3  * 订单类
 4  * @author sxf
 5  *
 6  */
 7 public class FutureResult extends Result{
 8     //真正的产品
 9     private Result result;
10     //产品是否生产好
11     private boolean ready=false;
12
13     //供生产线程使用,将生产好的产品放入订单
14     public synchronized void setResult(Result result){
15         this.result=result;
16         this.ready=true;
17         notifyAll();
18     }
19
20     //从订单里获取真正的产品结果
21     @Override
22     public synchronized Object getResultValue() {
23         while(!ready){
24             try {
25                 wait();
26             } catch (InterruptedException e) {
27                 // TODO Auto-generated catch block
28                 e.printStackTrace();
29             }
30         }
31         return result.getResultValue();
32     }
33
34
35 }

View Code

三:产品类

 1 package com.yeepay.sxf.thread12;
 2
 3 /**
 4  * 产品类
 5  * @author sxf
 6  *
 7  */
 8 public class RealResult extends Result {
 9     private final Object resultValue;
10
11     //制造产品的方法
12     public RealResult(Object resultValue) {
13         // TODO Auto-generated constructor stub
14          this.resultValue=resultValue;
15      }
16
17     //获得产品
18     @Override
19     public Object getResultValue() {
20
21         return resultValue;
22     }
23
24
25 }

View Code

四:工头和工人的接口

 1 package com.yeepay.sxf.thread12;
 2
 3 /**
 4  * 工头和工人的接口
 5  * @author sxf
 6  *
 7  */
 8 public interface ActiveObject {
 9     //制造字符串
10     public abstract Result makeString(int count,char fillchar);
11
12     //显示字符串
13     public abstract void displayString(String string);
14
15 }

View Code

五:工头类

 1 package com.yeepay.sxf.thread12;
 2
 3 /**
 4  * 发起制作操作的代理(工头)
 5  * @author sxf
 6  *
 7  */
 8 public class Poxy implements ActiveObject{
 9     //制造操作的线程
10     private final SchedulerTHread schedulerTHread;
11     //制造操作的工人
12     private final Servant servant;
13     //构造器
14     public Poxy(SchedulerTHread schedulerTHread,Servant servant){
15         this.schedulerTHread=schedulerTHread;
16         this.servant=servant;
17     }
18
19     /**
20      * 发起制造操作(开启制造操作的单据,并将制造原材料和制造工人打包,放入制造线程的队列中)
21      */
22     @Override
23     public Result makeString(int count, char fillchar) {
24         //制作一张订单
25         FutureResult future=new FutureResult();
26         //将原材料和工人和订单放入队列
27         schedulerTHread.Invoke(new MakeStringRequset(servant, future, count, fillchar));
28         //返回订单
29         return future;
30     }
31
32     /**
33      * 查看字符串
34      */
35     @Override
36     public void displayString(String string) {
37         //这个制造不需要订单
38         schedulerTHread.Invoke(new DisplayStringRequest(servant, string));
39     }
40
41
42 }

View Code

六:工人类

 1 package com.yeepay.sxf.thread12;
 2 /**
 3  * 执行者(工人)
 4  * @author sxf
 5  *
 6  */
 7
 8 public class Servant implements ActiveObject {
 9
10     /**
11      * 生产字符串
12      */
13     @Override
14     public Result makeString(int count, char fillchar) {
15         char[] buffer=new char[count];
16         for(int i=0;i<count;i++){
17             buffer[i]=fillchar;
18             try {
19                 Thread.sleep(100);
20             } catch (InterruptedException e) {
21                 // TODO Auto-generated catch block
22                 e.printStackTrace();
23             }
24         }
25         return new RealResult(buffer.toString());
26     }
27
28     /**
29      * 打印字符串
30      */
31     @Override
32     public void displayString(String string) {
33         System.out.println("Servant.displayString()"+string);
34         try {
35             Thread.sleep(10);
36         } catch (InterruptedException e) {
37             // TODO Auto-generated catch block
38             e.printStackTrace();
39         }
40
41     }
42
43
44 }

View Code

七:工作请求抽象的类

 1 package com.yeepay.sxf.thread12;
 2 /**
 3  * 执行请求的实例(工人,订单,原材料)
 4  * @author sxf
 5  *
 6  */
 7 public  abstract class MethodRequest {
 8     //工人
 9     protected final Servant servant;
10     //订单
11     protected final FutureResult future;
12
13     protected MethodRequest(Servant servant,FutureResult future) {
14         this.servant=servant;
15         this.future=future;
16     }
17     //工人的具体操作
18     public abstract void execute();
19 }

View Code

八:制造文字的请求

 1 package com.yeepay.sxf.thread12;
 2 /**
 3  * 制造字符串请求实例
 4  * 其做用:将制造的发起者和制造的执行者分离。
 5  * ==》方法的启动和方法的执行进行分离
 6  * ==》分离的本质:(1)启动者将执行请求转换成实例(原材料,执行者,订单)
 7  *                               (2)执行者用原材料生产完产品,将产品存入订单,供发起者使用
 8  * @author sxf
 9  *
10  */
11 public class MakeStringRequset extends MethodRequest{
12     private final int count;
13     private final char fillchar;
14     //构造器(制造工人,订单,产品原材料)
15     public MakeStringRequset(Servant servant,FutureResult futureResult,int count,char fillchar) {
16         super(servant, futureResult);
17         this.count=count;
18         this.fillchar=fillchar;
19     }
20
21     @Override
22     public void execute() {
23         //制造工人制造出产品
24         RealResult realResult=(RealResult) servant.makeString(count, fillchar);
25         //再将产品放入订单
26         future.setResult(realResult);
27     }
28
29
30 }

View Code

九:打印文字的请求

 1 package com.yeepay.sxf.thread12;
 2 /**
 3  * 打印字符串的请求实例
 4  * @author sxf
 5  *
 6  */
 7 public class DisplayStringRequest extends MethodRequest{
 8     //打印原材料
 9     private final String string;
10     public DisplayStringRequest(Servant servant,String string){
11         super(servant, null);
12         this.string=string;
13     }
14     //执行打印的方法
15     @Override
16     public void execute() {
17         servant.displayString(string);
18     }
19
20
21 }

View Code

十:十:客户线程(1)(发起制造字符串请求的线程)

 1 package com.yeepay.sxf.thread12;
 2
 3 /**
 4  * 发起制造字符串请求的线程
 5  * @author sxf
 6  *
 7  */
 8 public class MakerClientThread implements Runnable{
 9     //代理类(工头)
10     private final ActiveObject activeObject;
11     //生产原材料
12     private final char fillChar;
13
14     public MakerClientThread(ActiveObject activeObject,char fillChar) {
15         this.activeObject=activeObject;
16         this.fillChar=fillChar;
17     }
18
19     @Override
20     public void run() {
21         for(int i=0;true;i++){
22             //(工头)发起制造,得到订单
23             Result result=activeObject.makeString(i, fillChar);
24             //忙别的事情
25             try {
26                 Thread.sleep(1000);
27             } catch (InterruptedException e) {
28                 e.printStackTrace();
29             }
30             //从订单中获取产品结果
31             String value=(String) result.getResultValue();
32             //打印产品
33             System.out.println(Thread.currentThread().getName()+"=>value:["+value+"]");
34         }
35
36     }
37
38
39
40 }

View Code

十一:客户线程(2)发起打印字符串的请求线程

 1 package com.yeepay.sxf.thread12;
 2 /**
 3  * 发起打印字符串请求的线程
 4  * @author sxf
 5  *
 6  */
 7 public class DisplayClientThread implements Runnable{
 8     //工头
 9     private final ActiveObject activeObject;
10
11     public DisplayClientThread(ActiveObject activeObject){
12         this.activeObject=activeObject;
13     }
14
15     @Override
16     public void run() {
17         for(int i=0;true;i++){
18             //打印原材料
19             String string=Thread.currentThread().getName()+"  "+i;
20             //工头进行找人打印
21             activeObject.displayString(string);
22             try {
23                 Thread.sleep(200);
24             } catch (InterruptedException e) {
25                 // TODO Auto-generated catch block
26                 e.printStackTrace();
27             }
28         }
29
30     }
31
32 }

View Code

十二:生产线程

 1 package com.yeepay.sxf.thread12;
 2
 3
 4 /**
 5  * 制造线程(制造原材料==>原材料+工人)
 6  * @author sxf
 7  *
 8  */
 9 public class SchedulerTHread implements Runnable{
10     //制造线程中的队列
11     private final ActivationQueue activatonQueue;
12     public SchedulerTHread(ActivationQueue  activationQueue) {
13         this.activatonQueue=activationQueue;
14     }
15
16     //发起制造的线程,调用该方法,该方法是将制造请求(原材料+工人),放入队列
17     public void Invoke(MethodRequest request){
18         activatonQueue.putRequest(request);
19     }
20
21
22     //制造线程体
23     @Override
24     public void run() {
25         while(true){
26             //从队列中取出制造请求
27             MethodRequest request=activatonQueue.takeRequest();
28             //制造请求被执行
29             request.execute();
30         }
31
32
33     }
34
35
36 }

View Code

十三:客户线程和生产线程的队列

 1 package com.yeepay.sxf.thread12;
 2
 3 /**
 4  * 队列
 5  * @author sxf
 6  *
 7  */
 8 public class ActivationQueue {
 9     private static final int MAX_METHOD_REQUEST=100;
10     private final MethodRequest[] requestQueue;
11     private int tail;//下一个put Request的地方
12     private int head;//下一个take Request的地方
13     private int countRequest;//request的数量
14
15     public ActivationQueue() {
16         this.requestQueue=new MethodRequest[MAX_METHOD_REQUEST];
17         this.head=0;
18         this.tail=0;
19         this.countRequest=0;
20     }
21
22     //放入请求
23     public synchronized void putRequest(MethodRequest request){
24         while(countRequest>=requestQueue.length){
25             try {
26                 wait();
27             } catch (InterruptedException e) {
28                 // TODO Auto-generated catch block
29                 e.printStackTrace();
30             }
31         }
32         requestQueue[tail]=request;
33         //计算下一个放请求的位置
34         tail=(tail+1)%requestQueue.length;
35         //请求数加1
36         countRequest++;
37         //唤醒其他线程
38          notifyAll();
39     }
40
41     //取出请求
42     public synchronized MethodRequest takeRequest(){
43         while(countRequest<=0){
44             try {
45                 wait();
46             } catch (InterruptedException e) {
47                 // TODO Auto-generated catch block
48                 e.printStackTrace();
49             }
50         }
51         //取出
52         MethodRequest methodRequest=requestQueue[head];
53         //计算下一个取出请求的位置
54         head=(head+1)%requestQueue.length;
55         //请求数减去1
56         countRequest--;
57         //唤醒其他线程
58         notifyAll();
59         return methodRequest;
60     }
61 }

View Code

十四:产生工头的工厂类

 1 package com.yeepay.sxf.thread12;
 2
 3 /**
 4  * 工头对象的工厂类
 5  * @author sxf
 6  *
 7  */
 8 public class ActiveObjectFactory {
 9
10     //生产工头的对象
11     public static ActiveObject createActiveObject(){
12         //执行制造操作(工人)
13         Servant servant=new Servant();
14         //存放制造请求实例
15         ActivationQueue queue=new ActivationQueue();
16         //制造操作的线程
17         SchedulerTHread schedulerTHread=new SchedulerTHread(queue);
18         //发起制造动作(工头)
19         Poxy poxy=new Poxy(schedulerTHread, servant);
20         //启动制造操作的线程
21         new Thread(schedulerTHread).start();
22         return poxy;
23     }
24 }

View Code

十五:测试类

 1 package com.yeepay.sxf.thread12;
 2 /**
 3  * 测试类
 4  * @author sxf
 5  *
 6  */
 7 public class Test {
 8
 9     public static void main(String[] args) {
10         ActiveObject activeObject=ActiveObjectFactory.createActiveObject();
11         new Thread(new  MakerClientThread(activeObject, 's')).start();;
12         new Thread(new DisplayClientThread(activeObject)).start();
13
14     }
15 }

View Code

 

时间: 2024-09-28 01:34:33

多线程程序设计学习(13)Active Object pattern的相关文章

多线程程序设计学习(2)之single threaded execution pattern

Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResource(共享资源) 二:single threaded execution pattern模式什么时候使用--->多线程程序设计时--->数据可被多个线程访问的时候--->共享资源状态可能变化的时候--->需要确保数据安全性的时候 三:single threaded execution p

Active Object pattern

之所以叫, 主动对象, 区别于被动对象, 只能被动被别人调用的对象, 而主动对象内部有线程可以自行调用自己的方法.   Active Object是一种高级模式, 概念上和RPC有些类似, 但是实现和用途不一样 Active Object首先使用了Proxy模式, 这个和RPC一样, 用户可以象访问local function一样使用 然后Active Object关键的一步是使用command模式分离invacation和execution, proxy并没有直接运行调用逻辑, 而是封装成co

多线程程序设计学习(3)immutable pattern模式

Immutable pattern[坚不可摧模式] 一:immutable pattern的参与者--->immutable(不变的)参与者        1.1:immutable参与者是一个字段的值都无法更改的类.        1.2:immutable也没有任何用来更改字段值的方法.        1.3:immutable参与者方法不需要设置synchronized 二:immutable pattern模式什么时候使用--->当实例产生后,状态不再变化时        2.1实例状

多线程程序设计学习(7)read-write lock pattern

Read-Write Lock Pattern[读写]一:Read-Write Lock Pattern的参与者--->读写锁--->数据(共享资源)--->读线程--->写线程         二Read-Write Lock Pattern模式什么时候使用---> * 为了多线线程环境下保护数据安全,我们必须避免的冲突 * 一个线程读取,另一个线程写入的read-write conflick * 一个线程写入,另一个线程写入的write-write conflick *

多线程程序设计学习(10)Future pattern

Future pattern[订单取货模式] 一:Future pattern的参与者--->Client(客户需求)--->Host(蛋糕门店)--->Data(票据和蛋糕的接口)--->Future(蛋糕票据)--->ReaData(制作蛋糕过程)        二:Future pattern模式什么时候使用---> 三:Future pattern思考       ---> 四进阶说明        ---> 数据类接口 1 package com.

多线程程序设计学习(9)worker pattern模式

Worker pattern[工作模式]一:Worker pattern的参与者--->Client(委托人线程)--->Channel(通道,里边有,存放请求的队列)--->Request(工作内容的包装)--->Worker(工人线程)        二:Worker pattern模式什么时候使用--->类似生产者消费者 三:Worker pattern思考 四进阶说明--->工作线程取出请求内容包装后,根据多态,不同的请求执行不同的业务方法   Request接

多线程程序设计学习(12)Thread-soecific storage pattern

Thread-Specific-Storage[线程保管箱] 一:Thread-Specific Storage的参与者--->记录日志的线程(ClientThread)--->负责获取不同线程记录日志(Log)--->负责将日志写入文件的类(TsLog)         二:Thread-Specific Storage模式什么时候使用--->当每个线程必须有自己的独有信息时,可以将该信息放入线程保管箱ThreadLocal 三:Thread-Specific Storage思考

多线程程序设计学习(6)Producer-Consumer模式

Producer-Consumer[生产消费者模式]一:Producer-Consumer pattern的参与者--->产品(蛋糕)--->通道(传递蛋糕的桌子)--->生产者线程(制造蛋糕的线程)--->消费者线程(吃掉蛋糕的线程)         二:Producer-Consumer pattern模式什么时候使用--->大量生产+大量消费的模式 三:Producer-Consumer pattern思考--->[生产消费者模式],肩负保护数据安全性使命的是通道

多线程程序设计学习(5)balking模式和timed模式

Balking[返回模式]timed[超时模式]一:balking pattern的参与者--->GuardedObject(被警戒的对象) --->该模式的角色:模拟修改警戒对象的线程,当警戒条件达到执行具体操作的线程,参与者(被警戒的参与者)        二:balking pattern模式什么时候使用--->不需要刻意去执行什么操作的时候(比如说自动保存)--->不想等待警戒条件成立时.(不让线程休息)--->警戒条件只有第一次成立时候.    三:balking