【问题标题】:Java: allow worker thread to kill main threadJava:允许工作线程杀死主线程
【发布时间】:2013-01-10 05:02:27
【问题描述】:

我正在编写一个简单的 HTTP 服务器,其中主线程在 ServerSocket.accept 循环中循环,并将任何传入的套接字传递给工作线程,然后工作线程将处理它们并发回响应。但是,我想在特殊情况下关闭整个服务器的关闭请求。我在使用工作线程强制主线程跳出accept 循环并终止时遇到问题。

任何指针?

【问题讨论】:

    标签: java multithreading concurrency


    【解决方案1】:

    您可能会想出 100 种 hacky 方法来做到这一点,但在设计合理的应用程序中我只能看到 2 种方法。

    1. 这是处理代码的中断。

      while (acceptNextRequest()) {
          // Processing code
          if (shouldExitNow()) {
              break;
          }
          // More processing
      }
      // Proper exiting code
      
    2. 在接受下一个请求之前检查是否该退出:

      while (!shouldExitBeforeNextRequest() && acceptNextRequest()) {
          // Processing code
      }
      // Proper exiting code
      

    两种解决方案都确保正确关闭所有连接、向所有应用程序关闭侦听器发出通知等。

    如果您从 Web 应用程序执行 System.exit(),您将关闭整个 Web 服务器应用程序(Tomcat、JBoss 或任何用途),这通常不是您希望在应用程序中执行的操作。

    如果您在容器中运行应用程序,请不要弄乱主线程。

    【讨论】:

    • 是的,检查的唯一问题是ServerSocket已经在接受调用,所以它不能检查条件语句。 System.exit() 可能有效.. 虽然哈哈有点难看。谢谢!
    • 没关系。这一切都取决于实际的退出代码。实际上,Web 应用程序永远不应该被关闭。您可以注销 Web 应用程序,清除其状态,但绝不应使其对未来的请求不可用。
    • 我还没有看到要求退出 Web 应用程序的用户需求。这看起来更像是一种快速破解,不以正确的方式开发它。
    【解决方案2】:

    就像提到的in this thread 一样,您可以在服务器套接字上调用close(),这将导致accept 调用中的异常。

    【讨论】:

    • 啊,很脏,但可能是所有可能的解决方案中最干净且最容易处理的。谢谢!
    【解决方案3】:

    您是否尝试过使用workerThread.interrupt(); 中断工作线程?

    这应该会让accept 抛出一个InterruptedException,你可以捕获、清理需要清理的内容并退出工作线程。

    【讨论】:

    • 啊,但我想中断卡在接受调用中的主线程。我可以访问所有工作线程,并且我在工作线程中有标志,可以在必要时终止它们。不过感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 2022-10-16
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多