并发 Java 1.5 中的主动对象模式
我正在尝试使用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
中,state
为true
,因此传入消息应该等待,并且对当前消息调用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您等待相应的条件时,您必须实际获取锁。如果没有这个锁,您就无法直接将自己与条件关联起来。为了演示这一点:
这应该解决您的 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:
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();
andsuper.run();
lock.unlock()
will never be called.