Thread.stop和朋友在Java中是否安全? [英] Are Thread.stop and friends ever safe in Java?

查看:105
本文介绍了Thread.stop和朋友在Java中是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

stop() suspend(),以及 resume() in $ code> java.lang.Thread 已弃用,因为它们是不安全。 Sun推荐的解决方法是使用 Thread.interrupt(),但这种方法在所有情况下都不起作用。例如,如果您调用的库方法没有显式或隐式地检查中断的标志,那么您别无选择,只能等待调用完成。

The stop(), suspend(), and resume() in java.lang.Thread are deprecated because they are unsafe. The Sun recommended work around is to use Thread.interrupt(), but that approach doesn't work in all cases. For example, if you are call a library method that doesn't explicitly or implicitly check the interrupted flag, you have no choice but to wait for the call to finish.

所以,我想知道是否有可能描述(可证明)安全地调用 stop()在线程上。例如, stop()除了调用 find(...)之外什么都不做的线程是否安全?或 java.util.regex.Matcher 上匹配(...)

So, I'm wondering if it is possible to characterize situations where it is (provably) safe to call stop() on a Thread. For example, would it be safe to stop() a thread that did nothing but call find(...) or match(...) on a java.util.regex.Matcher?

(如果有任何Sun工程师正在阅读此内容,我们将非常感谢您的确定答案。)

(If there are any Sun engineers reading this ... a definitive answer would be really appreciated.)

编辑:简单地重述您不应该调用的咒语的答案 stop()因为它已被弃用,不安全,无论失踪这个问题的重点。我知道在大多数情况下它确实是不安全的,并且如果有可行的替代方案,你应该总是使用它。

EDIT: Answers that simply restate the mantra that you should not call stop() because it is deprecated, unsafe, whatever are missing the point of this question. I know that that it is genuinely unsafe in the majority of cases, and that if there is a viable alternative you should always use that instead.

这个问题是关于安全的子集案例。具体来说,什么是那个子集?

This question is about the subset cases where it is safe. Specifically, what is that subset?

推荐答案

这是我尝试回答我自己的问题。

Here's my attempt at answering my own question.

我认为以下条件应足以使用 Thread.stop()安全地停止单个线程:

I think that the following conditions should be sufficient for a single thread to be safely stopped using Thread.stop():


  1. 线程执行不得创建或改变其他线程可能看到的任何状态(即Java对象,类变量,外部资源)如果线程被停止。

  2. 线程执行在正常执行期间不得使用 notify 到任何其他线程。 / li>
  3. 线程不能开始加入其他线程,或者与之交互使用停止暂停恢复

  1. The thread execution must not create or mutate any state (i.e. Java objects, class variables, external resources) that might be visible to other threads in the event that the thread is stopped.
  2. The thread execution must not use notify to any other thread during its normal execution.
  3. The thread must not start or join other threads, or interact with then using stop, suspend or resume.

(上面的术语线程执行涵盖了所有应用程序级代码和线程执行的所有库代码。)

(The term thread execution above covers all application-level code and all library code that is executed by the thread.)

第一个条件意味着停止的线程不会使任何外部数据结构或资源处于不一致状态。这包括它可能在互斥锁中访问(读取)的数据结构。第二个条件意味着可停止的线程不能让其他线程等待。但它也禁止使用除了简单对象互斥体之外的任何同步机制。

The first condition means that a stopped thread will not leave any external data structures or resources in an inconsistent state. This includes data structures that it might be accessing (reading) within a mutex. The second condition means that a stoppable thread cannot leave some other thread waiting. But it also forbids use of any synchronization mechanism other that simple object mutexes.

可停止的线程必须能够将每个计算的结果传递给控制线程。这些结果由可停止的线程创建/变异,因此我们只需要确保它们在线程停止后不可见。例如,可以将结果分配给Thread对象的私有成员,并使用一个标志保护,该标志由线程原子地表示它已完成。

A stoppable thread must have a way to deliver the results of each computation to the controlling thread. These results are created / mutated by the stoppable thread, so we simply need to ensure that they are not visible following a thread stop. For example, the results could be assigned to private members of the Thread object and "guarded" with a flag that is atomically by the thread to say it is "done".

编辑:这些条件相当严格。例如,对于要安全停止的正则表达式求值程序线程,如果我们必须保证正则表达式引擎不会改变任何外部可见状态。问题是它可能会这样做,具体取决于你如何实现线程!

EDIT: These conditions are pretty restrictive. For example, for a "regex evaluator" thread to be safely stopped, if we must guarantee that the regex engine does not mutate any externally visible state. The problem is that it might do, depending on how you implement the thread!


  1. Pattern.compile(...)方法可能会更新静态缓存已编译的
    模式,如果他们这样做,他们将(应该)使用互斥量来执行此操作。 (实际上,OpenJDK 6.0版本不会缓存模式,但Sun可能会改变这种情况。)

  2. 如果你试图通过在控制线程中编译正则表达式并提供一个来避免1)预先实例化 Matcher ,然后正则表达式线程 突变外部可见状态。

  1. The Pattern.compile(...) methods might update a static cache of compiled patterns, and if they did they would (should) use a mutex to do it. (Actually, the OpenJDK 6.0 version doesn't cache Patterns, but Sun might conceivably change this.)
  2. If you try to avoid 1) by compiling the regex in the control thread and supplying a pre-instantiated Matcher, then the regex thread does mutate externally visible state.

在第一种情况下,我们可能会遇到麻烦。例如,假设使用HashMap实现缓存,并且在重组HashMap时线程被中断。

In the first case, we would probably be in trouble. For example, suppose that a HashMap was used to implement the cache and that the thread was interrupted while the HashMap was being reorganized.

在第二种情况下,我们会没问题提供 Matcher 尚未传递给其他线程,而提供控制器线程未尝试在停止正则表达式匹配器线程后使用匹配器

In the second case, we would be OK provided that the Matcher had not been passed to some other thread, and provided that the controller thread didn't try to use the Matcher after stopping the regex matcher thread.

那么这给我们留下了什么?

So where does this leave us?

好吧,我认为我已经确定了理论上可以安全停止线程的条件。我还认为理论上可以静态分析线程的代码(以及它调用的方法),看看这些条件是否总是成立。但是,我不确定这是否真的很实用。

Well, I think I have identified conditions under which threads are theoretically safe to stop. I also think that it is theoretically possible to statically analyse the code of a thread (and the methods it calls) to see if these conditions will always hold. But, I'm not sure if this is really practical.

这有意义吗?我错过了什么吗?

Does this make sense? Have I missed something?

编辑2

事情变得多了毛茸茸当你认为我们可能试图杀死的代码可能不受信任时:

Things get a bit more hairy when you consider that the code that we might be trying to kill could be untrusted:


  1. 我们不能依赖承诺 ;例如

  1. We can't rely on "promises"; e.g. annotations on the untrusted code that it is either killable, or not killable.

我们实际上需要能够阻止不受信任的代码执行可能会产生的任何内容,从而对不受信任的代码进行注释。根据确定的标准,它是不可杀戮的......

We actually need to be able to stop the untrusted code from doing things that would make it unkillable ... according to the identified criteria.

我怀疑这需要修改JVM行为(例如,实现运行时限制允许线程锁定或修改) ,或Isolates JSR的完整实现。这超出了我所考虑的公平游戏的范围。

I suspect that this would entail modifying JVM behaviour (e.g. implementing runtime restrictions what threads are allowed to lock or modify), or a full implementation of the Isolates JSR. That's beyond the scope of what I was considering as "fair game".

因此,现在让我们排除不受信任的代码案例。或者至少,承认恶意代码可以做一些事情来使自己不能安全地杀戮,并把这个问题放在一边。

So lets rule the untrusted code case out for now. Or at least, acknowledge that malicious code can do things to render itself not safely killable, and put that problem to one side.

这篇关于Thread.stop和朋友在Java中是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆