我正在尝试开发 active object pattern在并发 Java 中使用 java.util.concurrent
类。
我使用 Client
和 Server
来描述它。示例 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);
}
}
}
还有一个示例客户端
:
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
中的 state
为 true
时,传入的消息应该等待并且 await
在当前消息上被调用。但是,我得到 IllegalMonitorStateException
,这意味着当前消息不拥有要等待的当前线程。但是,我认为这很奇怪,因为当前消息是在 Server
及其线程池中调用的,因此当前消息也可以访问当前执行线程。
如果您提供任何想法或建议,或者使用 java.util.concurrent
实现此模式的已知工作实现,我将不胜感激。提前致谢。
更新:
我讨论了我可以在此 blog post 中部署的解决方案.希望对您有所帮助。
最佳答案
当您等待相应的条件时,您必须实际获取锁。没有那个锁,你就不能直接将自己与条件联系起来。为了证明这一点:
public void await() {
lock.lock();
try {
condition.await();
} catch(Exception e) {}
finally{
lock.unlock();
}
}
这应该可以解决您的 IllegalMonitorStateException
关于正确性的旁注,您应该始终以 try{ } finally{ } 方式释放锁,您可以观察我写的示例。原因是如果 lock().lock();
和 super.run();
lock.unlock()
之间发生异常> 永远不会被调用。
关于java - 并发 Java 1.5+ 中的 Activity 对象模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5166495/