并发 Java 1.5 中的主动对象模式

发布于 2024-10-20 01:47:24 字数 2392 浏览 9 评论 0原文

我正在尝试使用java.util.concurrent<在并发Java中开发活动对象模式 /代码> 类。

我使用客户端服务器来描述它。示例 Server 如下:

class Server implements Runnable {
  public final LinkedBlockingQueue que = new LinkedBlockingQueue();
  private final ExecutorService es = Executors.newCachedThreadPool();
  private Message currentMessage;

  private boolean state = false;

  public init() {
    es.submit(this);
  }

  public void requestForServer() {
    if (state) {
      this.currentMessage.await();
    }
    state = true;
  }

  public void run() {
     for(;;) {
       Message m = que.take();
       this.currentMessage = m;
       this.es.submit(m);           
     }
  }

}

示例 Client

class Client {

  private Server server;

  public Client(Server s) {
    this.server = s;
  }

  public void doSomething() {
    Message m = new Message(new Callable() {
      public Object call() {
        server.requestForServer();
      }
    });
    this.server.que.add(m);
  }

}

示例 Message 封装如下:

class Message<V> extends FutureTask<V> {
  private Lock lock = new ReentrantLock();
  private Condition condition = new Condition();

  public Message(Callable<V> callable) {
    super(callable);
  }

  public void run() {
    try {
      lock.lock();
      super.run();
      lock.unlock();
    } catch(Exception e) {}
  }

  public void await() {
    try {
      condition.await();
    } catch(Exception e) {}
  }

  public void signal() {
    try {
      condition.signalAll();
    } catch(Exception e) {}
  }

}

示例运行代码:

Server s = new Server();
Client c = new Client (s);
s.init();
c.doSomething();

我删除了一些实现细节来传达我的消息。

现在,问题是在Server中,statetrue,因此传入消息应该等待,并且对当前消息调用 await 。但是,我得到 IllegalMonitorStateException 这意味着当前消息不拥有当前线程来等待它。但是,我认为这很奇怪,因为当前消息在服务器及其线程池中被调用,因此当前消息还可以访问当前执行线程。

我将非常感谢任何想法或建议,或者使用 java.util.concurrent 的已知工作实现。提前致谢。

更新
我在此 博客中讨论了可以部署的解决方案发布。我希望它能有所帮助。

I am trying to develop active object pattern in concurrent Java using java.util.concurrent classes.

I describe it using a Client and a Server. A sample Server is as:

class Server implements Runnable {
  public final LinkedBlockingQueue que = new LinkedBlockingQueue();
  private final ExecutorService es = Executors.newCachedThreadPool();
  private Message currentMessage;

  private boolean state = false;

  public init() {
    es.submit(this);
  }

  public void requestForServer() {
    if (state) {
      this.currentMessage.await();
    }
    state = true;
  }

  public void run() {
     for(;;) {
       Message m = que.take();
       this.currentMessage = m;
       this.es.submit(m);           
     }
  }

}

And a sample Client:

class Client {

  private Server server;

  public Client(Server s) {
    this.server = s;
  }

  public void doSomething() {
    Message m = new Message(new Callable() {
      public Object call() {
        server.requestForServer();
      }
    });
    this.server.que.add(m);
  }

}

And a sample Message encapsulation is:

class Message<V> extends FutureTask<V> {
  private Lock lock = new ReentrantLock();
  private Condition condition = new Condition();

  public Message(Callable<V> callable) {
    super(callable);
  }

  public void run() {
    try {
      lock.lock();
      super.run();
      lock.unlock();
    } catch(Exception e) {}
  }

  public void await() {
    try {
      condition.await();
    } catch(Exception e) {}
  }

  public void signal() {
    try {
      condition.signalAll();
    } catch(Exception e) {}
  }

}

And a sample running code:

Server s = new Server();
Client c = new Client (s);
s.init();
c.doSomething();

I dropped some implementation details to get my message across.

Now, the problem is when in Server the state is true so the incoming message should wait and the await is called on the current message. However, I get IllegalMonitorStateException which means that the current message does not own the current thread to await on it. But, I believe this is strange since the current message gets called in the Server and its thread pool so the current message has also an access to the current thread of execution.

I'd be most thankful for any ideas or suggestions, or with a known working implementation of this pattern using java.util.concurrent. Thanks in advance.

UPDATE:
I discussed the solution I could deploy in this blog post. I hope it could help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑,眼淚并存 2024-10-27 01:47:24

当您等待相应的条件时,您必须实际获取锁。如果没有这个锁,您就无法直接将自己与条件关联起来。为了演示这一点:

  public void await() {
    lock.lock();
    try {
      condition.await();
    } catch(Exception e) {}
    finally{
      lock.unlock();
    }
  }

这应该解决您的 IllegalMonitorStateException

在正确性方面,您应该始终以 try{ } finally{ } 方式释放锁,您可以观察我作为示例编写的内容。原因是如果 lock().lock();super.run(); lock.unlock(); 之间发生异常> 永远不会被调用。

You have to actually acquire the lock when you await on its corresponding condition. Without that lock you cannot associate yourself to the condition directly. To demonstrate this:

  public void await() {
    lock.lock();
    try {
      condition.await();
    } catch(Exception e) {}
    finally{
      lock.unlock();
    }
  }

That should resolve your IllegalMonitorStateException

On a side note of correctness you should always release a lock in a try{ } finally{ } manner, you can observe what I wrote as an example. The reason for this is if an exception occurs between lock().lock(); and super.run(); lock.unlock() will never be called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文