Java 从不同线程中的消息循环返回操作结果

Java 从不同线程中的消息循环返回操作结果,java,multithreading,Java,Multithreading,我有一些关于“消息循环”的理论问题;特别是返回在不同线程中运行的消息循环中发生的操作的结果。我遇到的情况是,有一个TCP服务器正在侦听传入的消息。对于每个传入消息,服务器将对发送消息的客户端进行身份验证,可能会发生两种情况: 如果经过身份验证的客户端具有附加的处理程序,则接收到的消息将传递给处理程序的消息队列 如果客户端没有处理程序,将创建一个新的处理程序,与上面相同(消息将传递到其消息队列) 处理程序当前是一个实现可调用接口的对象,因此它将在不同的线程中运行,并且它足够简单,可以获得操作的结果

我有一些关于“消息循环”的理论问题;特别是返回在不同线程中运行的消息循环中发生的操作的结果。我遇到的情况是,有一个TCP服务器正在侦听传入的消息。对于每个传入消息,服务器将对发送消息的客户端进行身份验证,可能会发生两种情况:

  • 如果经过身份验证的客户端具有附加的处理程序,则接收到的消息将传递给处理程序的消息队列
  • 如果客户端没有处理程序,将创建一个新的处理程序,与上面相同(消息将传递到其消息队列)
  • 处理程序当前是一个实现可调用接口的对象,因此它将在不同的线程中运行,并且它足够简单,可以获得操作的结果。现在来解决我的问题:每个处理程序可以有N个要处理的消息量。该处理程序有一个类似“消息循环”的功能,在超时发生之前一直运行—在本例中,超时是套接字到达预定义树阈值的空闲时间。我想知道的是,如何让Java在不终止线程的情况下从消息循环中返回值。如下所示:

    while (true) {
        if (expired(socket))
            break; // the callable will finish the call() method.
    
        // get the first item from the queue.
        message = messageQueue.poll();
    
        result = process(message);
    
        // I want to return the result to the caller which is in a different thread.
    }
    
    现在很明显,return语句将停止消息循环,如果messageQueue包含更多的消息,它们将丢失。另一种天真的方法是使用类似回调的机制,这需要一个额外的对象+我仍然需要在后台线程中将调用方与可调用方同步。类似于wait¬ify的东西,尽管我有K个线程在后台运行

    在不终止线程本身的情况下,处理从不同线程的消息循环中返回操作结果这种情况的复杂方法是什么

    @编辑: 我将对整个过程进行描述,以便澄清这里发生的事情

  • 客户端通过tcp套接字向应用程序发送消息(xml字符串)
  • 应用程序对客户端进行身份验证,如果客户端没有关联的处理程序,它将创建一个
  • 应用程序将消息推送到处理程序的队列中
  • 处理程序在一个单独的线程中运行,等待来自与之关联的客户端的传入消息,它们不能处理其他客户端的消息
  • 当处理程序拾取一条消息时,它会将其转换为SOAP消息,并通过TCP套接字将其转发到另一个系统
  • 当处理程序接收到响应时,它需要将其委托回调用方,而不终止其消息循环
  • 因此,调用者类似于一个调度器,它将消息分派给运行与消息发送者相关联的处理程序的线程。它还从处理程序收集响应,并将它们发送回正确的客户端

    每个处理程序当前都有自己的消息队列,其中只推送特定处理程序必须处理的消息。当处理程序启动时,它将打开一个到目标系统的TCP套接字,在应用转换后,它们将转发传入的消息。当处理程序达到允许的最大空闲时间(套接字在未发送请求的情况下打开)时,套接字将关闭,消息循环停止。此时,处理程序将完成其执行。这样做的目的是为每个客户机提供一个套接字,通过该套接字,他们可以发送多个请求,而无需目标系统进行另一次身份验证。

    这取决于。。。 如果要返回简单类型,可以使用AD安全结果队列(全局或按调用方)。 可能线程池更适合您的情况


    我相信最普遍的方法是回调机制。

    我想到的选项/问题很少:

  • 终止线程、检查返回的结果,然后将此任务重新提交到同一线程池是否有问题?您将得到一个结果,对其进行分析,然后重新提交到池并继续工作

  • 当这个线程运行时,它可以将状态提交到一个不同的(“外部”)队列,该队列在这个线程之外进行分析。独立线程始终运行并检查此队列


  • 这就是我所能想到的如何……

    如果您想看看这样的东西,SwingWorker的实现(虽然不是完美的)是一个很好的开始
    javax.swing.SwingWorker
    几乎完全实现了您解释的行为类型。回调机制的问题在于,当我在线程内调用回调方法时,回调方法将在线程内运行,而不是在调用方内运行。我想要的是从线程向调用者发出信号,让调用者执行一个函数,而不让调用者停止它实际执行的操作。同时,我会看一看SwingWorker。在这种情况下(如果你真的想在调用线程中准备结果),我会在调用线程中使用结果队列,有时会检查它。或者在异步调用中使用EventBus模式(如果你想在另一个线程中准备结果),不幸的是,线程终止超出了范围,但我故意忽略了它。流程操作意味着转发消息并读取其响应。如果我要终止线程,套接字将在我们转发消息的系统中关闭或悬挂。我会更新我原来的帖子来反映它。第二点似乎是一个很好的选择,我来看看。我坚持你的第二个选择。我实施了这个解决方案,就我的需求而言,它似乎相当直接和灵活。谢谢你的回答!