简体   繁体   English

阻塞线程,直到它从其他线程(java)获得特定信号为止

[英]block a thread until it gets a specific signal from some other thread (java)

I have an java server application communicating with clients via sockets. 我有一个Java服务器应用程序通过套接字与客户端通信。 Every client request is handled in a new thread. 每个客户端请求都在一个新线程中处理。 But for some requests I need to synchronize two clients. 但是对于某些请求,我需要同步两个客户端。

Example: 例:

  • Client A sends a request to the Server S. 客户端A向服务器S发送请求。
  • Thread S1 on S accepts the request of A. S上的线程S1接受A的请求。
  • S1 informs Client B about this request (via GoogleCloudMessaging). S1通过GoogleCloudMessaging通知客户端B此请求。
  • S1 SHOULD BLOCK NOW S1现在应该阻止
  • Client B receives the information from S and sends a request to S. 客户端B从S接收信息,并向S发送请求。
  • Thread S2 on S accepts the request of B. S上的线程S2接受B的请求。
  • S1 SHOULD BE RELEASED NOW and get the message from S2 现在应该释放S1并从S2获取消息
  • S1 sends the answer to Client A S1将答案发送给客户端A

I know about the Lock Condition mechanism, but this does not work here, because I don't know the condition when creating the threads. 我知道锁定条件机制,但这在这里不起作用,因为我不知道创建线程时的条件。 I need something like: 我需要类似的东西:

// Pseudo Code
// on the S1 Thread, first argument beeing a signal ID, second a timeout
s1.waitForSignal("clientB", 10000);
// and on the S2 Thread to continue S1
SignalSender.send("clientB");

Is anything like this possible in Java? 在Java中有可能发生这种情况吗? Is there any other solution for my problem? 我的问题还有其他解决方案吗?

Your problem seems to be that you do not have a shared reference on which you could invoke wait / notify (not to mention a shared lock condition that you could use). 您的问题似乎是您没有可以在其上调用wait / notify的共享引用(更不用说可以使用的共享锁定条件了)。

Well, first of all there is stuff shared between those two threads already: namely, in your case, the string "ClientB" . 好吧,首先,这两个线程之间已经共享了一些东西:即,在您的情况下,字符串"ClientB" If you have this, all you need to do is map that string to a single reference in a place that is accessible by both classes. 如果有这个功能,您要做的就是将该字符串映射到两个类都可以访问的地方的单个引用。

The simplest implementation would be to hold a static map field somewhere and just fill it with monitor objects somehow: 最简单的实现是将静态映射字段保存在某个地方,然后以某种方式用监视对象填充它:

public final class Monitors {

    private Monitors() {}

    private static final Map<String, Object> monitors = new HashMap<String, Object>();

    static { monitors.put("ClientB", new Object()); }

    public static Object get(String key) { return monitors.get(key); }

}

Of course, you may want to write a proper service that manages this mapping and perhaps uses locks and conditions internally. 当然,您可能想编写一个适当的服务来管理此映射,并可能在内部使用锁和条件。 Also, a good idea would be to encapsulate the waiting and signaling functionality within the service itself and then use it like: monitorService.waitForSignalsFrom("ClientB") . 同样,一个好主意是将等待和信令功能封装在服务本身内,然后像下面那样使用它: monitorService.waitForSignalsFrom("ClientB")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM