1

我在java应用程序和jax-ws Web服务之间的线程间通信中发布的原始问题改变了一些前提(我也在简化问题以使其更易于理解(并因此得到回答)......希望版主没问题.)

Web 服务线程 (THREAD-1) 将请求放在套接字上并进入睡眠状态等待响应。另一个侦听器线程 (THREAD-2)(作为单独的 Web 应用程序运行,一旦收到响应)必须将 THREAD-1 从睡眠中唤醒。

我该怎么做(以推送通知的方式)?

他们都可以访问数据库表。THREAD-1 可以在进入睡眠状态之前将其唯一的 id 放入表中。THREAD-2,一旦它收到响应并确定它属于 THREAD-1,它就会更新数据库表中的相应行。现在 THREAD-1 可以对数据库表进行轮询(定期)以检查响应是否已到达。

但我希望以推送通知的方式进行。当响应到达时应该立即通知 THREAD-1,而不必每隔几秒轮询一次。

4

2 回答 2

3

如果您的后端请求快速完成并且您没有大量的客户端请求需要处理,您可以让 Web 服务通过它刚刚打开的同一个套接字等待响应。它可以阻止等待读取响应。

但是,如果您可以访问 Servlet 3.0(例如 Tomcat 7),则可以使用异步 HTTP 请求。它允许您将处理 Web 服务客户端的线程释放回池中,而无需响应客户端的请求。当响应消息从后端服务到达时,从 servlet 容器中获取适当的 Web 服务客户端请求并将最终响应发送回 Web 服务客户端。

于 2012-07-14T19:22:17.030 回答
2

好吧,正如评论所暗示的那样:最好不要自己尝试实现这一点。但是,基本上您可以使用带有 wait()/notify() 的标准 Java 线程同步

  • Thread-1 组对 Thread-2 的远程调用以及唯一的 call-ID。
  • Thread-1 现在wait()在同步对象上(而不是sleep()
  • Thread-2 完成工作并返回结果,它调用 JVM 中的一些远程回调方法 Thread-1 驻留在其中 - call-ID 与结果一起传递
  • Thread-1 端的回调方法通过 call-ID 使结果可用,并通过以下方式唤醒所有等待的线程notifyAll()
  • 线程包括。Thread-1 检查他们的结果是否到达,如果是,他们继续工作,如果没有,则wait()再次。

Thread-1 端的伪代码:

HashMap<String, Object> results;

// Called by Thread-1 to access Thread-2
public void doIt() {
    String callId = "aUniqueCallId";
    Object result = null;
    remoteCallToThread2(callId);
    synchronized(results) {
        while((result = results.remove(callId)) == null) {
            results.wait();
        }
    }
    doSomethingWith(result);
}

// Called remotely by Thread-2 when result is available
public void callback(String callId, Object result) {    
    synchronized(results) {
        results.put(callId, result);
        results.notifyAll();
    } 
}

当然这只是基本思路,不能这样用,这里要考虑的东西很多。

于 2012-07-14T18:27:56.113 回答