Active Object 设计模式实战

x33g5p2x  于2022-05-05 转载在 其他  
字(6.4k)|赞(0)|评价(0)|浏览(482)

一 Result

  1. package concurrent.activeobjects;
  2. public interface Result {
  3. Object getResultValue();
  4. }

二 RealResult

  1. package concurrent.activeobjects;
  2. public class RealResult implements Result {
  3. private final Object result;
  4. public RealResult(Object reslut) {
  5. this.result = reslut;
  6. }
  7. @Override
  8. public Object getResultValue() {
  9. return result;
  10. }
  11. }

三 FutureResult

  1. package concurrent.activeobjects;
  2. public class FutureResult implements Result {
  3. private Result result;
  4. private boolean ready = false;
  5. public synchronized void setResult(Result result) {
  6. this.result = result;
  7. this.ready = true;
  8. this.notifyAll();
  9. }
  10. @Override
  11. public synchronized Object getResultValue() {
  12. while (!ready) {
  13. try {
  14. this.wait();
  15. } catch (InterruptedException e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. return this.result.getResultValue();
  20. }
  21. }

四 MethodRequest

  1. package concurrent.activeobjects;
  2. /**
  3. * @className: MethodRequest
  4. * @description: 对应 ActiveObject 的每一个方法
  5. * @date: 2022/5/3
  6. * @author: cakin
  7. */
  8. public abstract class MethodRequest {
  9. protected final Servant servant;
  10. protected final FutureResult futureResult;
  11. public MethodRequest(Servant servant, FutureResult futureResult) {
  12. this.servant = servant;
  13. this.futureResult = futureResult;
  14. }
  15. public abstract void execute();
  16. }

五 MakeStringRequest

  1. package concurrent.activeobjects;
  2. public class MakeStringRequest extends MethodRequest {
  3. private final int count;
  4. private final char fillchar;
  5. public MakeStringRequest(Servant servant, FutureResult futureResult, int count, char fillChar) {
  6. super(servant, futureResult);
  7. this.count = count;
  8. this.fillchar = fillChar;
  9. }
  10. @Override
  11. public void execute() {
  12. Result result = servant.makeString(count, fillchar);
  13. futureResult.setResult(result);
  14. }
  15. }

六 DisplayStringRequest

  1. package concurrent.activeobjects;
  2. public class DisplayStringRequest extends MethodRequest {
  3. private final String text;
  4. public DisplayStringRequest(Servant servant, final String text) {
  5. super(servant, null);
  6. this.text = text;
  7. }
  8. @Override
  9. public void execute() {
  10. this.servant.displayString(text);
  11. }
  12. }

七 ActivationQueue

  1. package concurrent.activeobjects;
  2. import java.util.LinkedList;
  3. public class ActivationQueue {
  4. private final static int MAX_METHOD_REQUEST_QUEUE_SIZE = 100;
  5. private final LinkedList<MethodRequest> methodQueue;
  6. public ActivationQueue() {
  7. methodQueue = new LinkedList<>();
  8. }
  9. public synchronized void put(MethodRequest request) {
  10. while (methodQueue.size() >= MAX_METHOD_REQUEST_QUEUE_SIZE) {
  11. try {
  12. this.wait();
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. this.methodQueue.addLast(request);
  18. this.notifyAll();
  19. }
  20. public synchronized MethodRequest take() {
  21. while (methodQueue.isEmpty()) {
  22. try {
  23. this.wait();
  24. } catch (InterruptedException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. MethodRequest methodRequest = methodQueue.removeFirst();
  29. this.notifyAll();
  30. return methodRequest;
  31. }
  32. }

八 SchedulerThread

  1. package concurrent.activeobjects;
  2. public class SchedulerThread extends Thread {
  3. private final ActivationQueue activationQueue;
  4. public SchedulerThread(ActivationQueue activationQueue) {
  5. this.activationQueue = activationQueue;
  6. }
  7. public void invoke(MethodRequest request) {
  8. this.activationQueue.put(request);
  9. }
  10. @Override
  11. public void run() {
  12. while (true) {
  13. activationQueue.take().execute();
  14. }
  15. }
  16. }

九  ActiveObject 

  1. package concurrent.activeobjects;
  2. /**
  3. * @className: ActiveObject
  4. * @description: 接受异步消息的主动对象
  5. * @date: 2022/5/3
  6. * @author: cakin
  7. */
  8. public interface ActiveObject {
  9. Result makeString(int count, char fillChar);
  10. void displayString(String text);
  11. }

十 Servant

  1. package concurrent.activeobjects;
  2. import java.util.concurrent.TimeUnit;
  3. class Servant implements ActiveObject {
  4. @Override
  5. public Result makeString(int count, char fillChar) {
  6. char[] buf = new char[count];
  7. for (int i = 0; i < count; i++) {
  8. buf[i] = fillChar;
  9. try {
  10. Thread.sleep(10);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15. return new RealResult(new String(buf));
  16. }
  17. @Override
  18. public void displayString(String text) {
  19. System.out.println("Display is " + text);
  20. try {
  21. TimeUnit.SECONDS.sleep(1);
  22. } catch (InterruptedException e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. }

十一 ActiveObjectProxy

  1. package concurrent.activeobjects;
  2. class ActiveObjectProxy implements ActiveObject {
  3. private final SchedulerThread schedulerThread;
  4. private final Servant servant;
  5. public ActiveObjectProxy(SchedulerThread schedulerThread, Servant servant) {
  6. this.schedulerThread = schedulerThread;
  7. this.servant = servant;
  8. }
  9. @Override
  10. public Result makeString(int count, char fillChar) {
  11. FutureResult future = new FutureResult();
  12. schedulerThread.invoke(new MakeStringRequest(servant, future, count, fillChar));
  13. return future;
  14. }
  15. @Override
  16. public void displayString(String text) {
  17. schedulerThread.invoke(new DisplayStringRequest(servant, text));
  18. }
  19. }

十二 ActiveObjectFactory

  1. package concurrent.activeobjects;
  2. public final class ActiveObjectFactory {
  3. public ActiveObjectFactory() {
  4. }
  5. public static ActiveObject createAcitveObject() {
  6. Servant servant = new Servant();
  7. ActivationQueue queue = new ActivationQueue();
  8. SchedulerThread schedulerThread = new SchedulerThread(queue);
  9. ActiveObjectProxy proxy = new ActiveObjectProxy(schedulerThread, servant);
  10. schedulerThread.start();
  11. return proxy;
  12. }
  13. }

十三 DisplayClientThread

  1. package concurrent.activeobjects;
  2. public class DisplayClientThread extends Thread {
  3. private final ActiveObject activeObject;
  4. public DisplayClientThread(String name, ActiveObject activeObject) {
  5. super(name);
  6. this.activeObject = activeObject;
  7. }
  8. @Override
  9. public void run() {
  10. try {
  11. for (int i = 0; true; i++) {
  12. String text = Thread.currentThread().getName() + "=>" + i;
  13. activeObject.displayString(text);
  14. Thread.sleep(200);
  15. }
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. }

十四 MakeClientThread

  1. package concurrent.activeobjects;
  2. public class MakeClientThread extends Thread {
  3. private final ActiveObject activeObject;
  4. private final char fillChar;
  5. public MakeClientThread(ActiveObject activeObject, String name) {
  6. super(name);
  7. this.activeObject = activeObject;
  8. this.fillChar = name.charAt(0);
  9. }
  10. @Override
  11. public void run() {
  12. try {
  13. for (int i = 0; true; i++) {
  14. Result result = activeObject.makeString(i + 1, fillChar);
  15. Thread.sleep(20);
  16. Object value = (String) result.getResultValue();
  17. System.out.println(Thread.currentThread().getName() + ": value " + value);
  18. }
  19. } catch (InterruptedException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. }

十五 Test

  1. package concurrent.activeobjects;
  2. public class Test {
  3. public static void main(String[] args) {
  4. ActiveObject activeObject = ActiveObjectFactory.createAcitveObject();
  5. new MakeClientThread(activeObject, "Alice").start();
  6. new MakeClientThread(activeObject, "Bobby").start();
  7. new DisplayClientThread("Chris", activeObject).start();
  8. }
  9. }

十六 测试结果

Alice: value A

Bobby: value B

Display is Chris=>0

Alice: value AA

Display is Chris=>1

Bobby: value BB

Display is Chris=>2

Display is Chris=>3

Display is Chris=>4

Display is Chris=>5

Alice: value AAA

Display is Chris=>6

Bobby: value BBB

Display is Chris=>7

Display is Chris=>8

Display is Chris=>9

Display is Chris=>10

Display is Chris=>11

Display is Chris=>12

Display is Chris=>13

Display is Chris=>14

Display is Chris=>15

相关文章