2012-07-14 150 views
1

某些前提在我原来的问题上发生了变化inter-thread communication between java application and jax-ws web service(我也在简化问题以使它更容易理解(并因此得到回答)......希望没关系版主。)java web应用程序和web服务之间的线程间通信

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

我该如何做(推送通知方式)?

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

但我期待以推送通知的方式做到这一点。应答到达时应立即通知THREAD-1,而不必每隔几秒轮询一次。

+1

第一反应,而阅读此:*不这样做*。第二:*不要自己动手*。这是消息排队。所以找到一个解决方案/产品/框架,可以让您在数据库之上处理消息排队。 – Arne 2012-07-14 17:50:27

+0

我认为消息队列更适合异步通信,在我的情况下,THREAD-1无法将请求放入队列并忘记它 - 它实际上必须等待阻塞模式以获取其响应以更新其调用客户端(web服务客户在这种情况下)关于收到的响应。这是我为什么不应该在这种情况下使用消息队列的第一个推理。 – 2012-07-14 18:23:49

回答

2

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

  • 线程1套远程调用与线程2连同唯一的呼叫ID。
  • 线程1现在wait()确实同步对象(而不是sleep()
  • 线程2做的工作,并返回它调用在JVM中一些远程回调方法线程1驻留在结果上 - 呼叫ID与结果一起传递
  • Thread-1端的回调方法使结果通过呼叫ID可用,并通过notifyAll()
  • 唤醒所有等待的线程。线程1检查他们的结果是否到达,如果是,他们继续工作,如果没有wait()再次。为线程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(); 
    } 
} 

当然这只是一个基本的想法,不能被用作这样的,有很多的东西在这里考虑。

+0

感谢您的详细回复@lost。但是,如果你能评论我的理由,不希望使用基于消息队列的解决方案,我将不胜感激。 **当THREAD-1(来自web CLiENT-1的web服务调用的一个实例)发送请求(通过套接字)时,它必须在发送请求后立即释放该套接字。 还有另一个监听器线程持续监听该套接字的响应,但这些响应可能会失序,因此此监听器线程必须查看每个响应并通知相应的等待线程其响应已到达。 – 2012-07-14 18:54:51

+0

如果有人(包括@Arne)能够解释如何通过消息队列来实现这个功能,那将是非常好的选择。我当然更喜欢那条路线,因为我不必处理那些细节中的线程。 – 2012-07-14 18:55:36

+0

我的回答与Thread-2的回调无关。它可以通过直接来自Thread-2的WS调用来完成,它也可以通过MQ系统上的消息进入。如果你不想让线程1阻塞,那么wait()/ notify()是要走的路。当你刚刚从Thread-1到Thread-2(不知道这些框架的细节)发起同步WS调用时,我提出的建议已经包含在常见的WS框架中。如果是这种情况,这将是最简单的解决方案。你必须检查你的框架的属性。 – lost 2012-07-14 19:42:33

3

如果您的后端请求很快完成,并且您不会有客户端请求处理的洪流,您可以让Web服务通过刚才打开的同一个套接字等待响应。它可以阻止等待读取响应。但是,如果您有权访问Servlet 3.0(例如Tomcat 7),则可以使用asynchronous HTTP requests。它允许您将处理Web服务客户端的线程释放回池中,而无需响应客户端的请求。当响应消息从后端服务到达时,从servlet容器中抓取相应的Web服务客户端请求,并将最终响应发送回Web服务客户端。

+0

这将是eas即将实施,并且我将在明天与传统平台团队*(我们在此案例中向传统平台打开套接字)确认此设计。他们昨天告诉我THREAD-1发送一个请求到套接字并释放套接字上的句柄。由于这种Web服务将被多个Web客户端(多个用户在互联网上访问Web服务)调用,所以它们都可以并行地提出请求,并且响应可以在他们执行时返回。如果我们按照你的建议,吞吐量将大幅下降 – 2012-07-14 19:44:07

+0

我的印象是这些后端请求很快就完成了。因此,请参阅我的编辑。 – 2012-07-14 20:03:01

+0

thx您的建议@David Harkness - 这就像一个混合的解决方案,似乎并不需要与线程等待/通知模式工作,并自动照顾匹配响应与他们相应的请求线程..(一厢情愿的想法 - 我会在阅读该链接后确认这一点,现在就快速查找,看起来_PROMISING_).. – 2012-07-14 21:11:27

相关问题