【问题标题】:Java: stopping a thread with no synchronizationJava:停止没有同步的线程
【发布时间】:2018-01-08 07:08:51
【问题描述】:

TL;DR 当我知道它没有与其他任何东西同步时,它可以用于 Java 线程吗?

首先我将描述我的困境。我有一个服务来处理来自应用程序的请求(都在同一台机器上)。该服务是单线程的。在某些情况下,回答请求可能需要一段时间。在这些情况下,我想暂停请求。 遗憾的是,在所述服务内部轮询中断非常复杂,因为它具有相当广泛的算法逻辑,并且会导致大量丑陋的代码重写。

将服务视为调用可怕算法库的外观。 目前该服务只是根据请求调用库,我希望它启动一个线程,如果计算时间过长,它会超时。 我打算只使用一个额外的线程。

我读过How do you kill a thread in Java? 和https://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

根据这些,由于失去同步,不推荐停止线程。但是,我的服务基本上是单线程的,因此不需要同步。

在这种情况下,我可以停止线程吗?我错过了一些内部 java 的东西吗?

谢谢!

【问题讨论】:

  • 能分享一下代码吗?
  • 是单线程的,但是要停止线程?那么这是否意味着您要退出该流程?
  • @egorlitvinenko 嗯...我不认为我可以。但是,我认为您在这里并不需要它。将服务想象成一个包含多种方法的库的外观,这些方法都是算法和可怕的。
  • @matt 目前,该服务只是运行一些代码。我希望服务在不同的线程上运行代码,如果运行时间过长则终止线程
  • 您可以做的一件事是启动另一个进程,而不是启动另一个线程。然后,您可以完全控制启动或停止该过程。这基本上就是您描述生成的线程的方式。

标签: java multithreading synchronization java-threads


【解决方案1】:

因此,您有一个处理请求的服务,有时该处理可能需要一段时间。您希望在放弃之前规定您的服务可以花在处理该请求上的最大时间。

您不想在代码中乱扔对某个中断设置的标志的检查,因为代码又大又复杂。

您的选择:

  1. 不要放弃。

在单独的线程上处理每个请求。允许每个请求运行完成,尽可能多地花费时间。考虑改进服务请求代码,或许使用并行性,以减少运行所需的时间。

  1. 使用“停止时间”检查乱扔代码。

这是第二好的答案 - 您可以控制您的程序决定停止处理响应的位置。您的程序可以可控地关闭请求处理,适当地清理它需要的任何东西(可能是打开的资源,如文件、套接字等;在内部重置程序状态)。

  1. 杀死线程。

不推荐调用Thread.stop(),这是有充分理由的——它可能会破坏同步状态。如果您的请求处理逻辑使用任何形式的同步,那么您将导致损坏。请记住,同步无处不在,即使您看不到它。从文件中读取使用了一种同步形式。写入标准输出使用同步。

这是可能的,但这是一个糟糕的主意。

...

还有其他与 #2 相关的策略 - 例如,您可以重组程序,以便将每个处理部分创建为队列上的作业,一个线程负责出列和执行 - 基本上,消息泵图案。在这个设计中,你会有一个很好的阻塞点来放置你的“超时”逻辑。这是大多数窗口框架使用的设计 - UI 消息泵。

【讨论】:

  • 谢谢!这正是我想要的。
  • 你的第 3 点有点夸张。 Thread.stop 并不比 OutOfMemoryError 或任何其他意外的 RuntimeException 或错误差。它们都很糟糕,它们可以破坏任何数据结构的不变量,包括由多个线程共享的不变量。它不会锁定任何监视器,也不会破坏文件读取或标准输出(这是操作系统级别的东西,不受 Thread.stop 影响)。 Thread.stop 向线程中抛出意外异常,如果您愿意,可以在代码中处理。不过,在干净、生产、代码中应该避免它。
  • 您能否解释或提供链接,我们如何处理队列处理中的超时,而不影响Java中的原始代码?
  • @egorlitvinenko - 这是#2的中心论点:你不能。您必须以某种方式修改或重组代码,但如果您愿意这样做,您可以使用多种策略。如果您不是在寻找刺激,通常无法让您的代码对刺激做出响应。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 2013-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多