Java thread.stop()如何工作?

时间:2012-10-31 08:41:19

标签: java multithreading

我实际上正在寻找一种更简单的方法来杀死线程,而不管线程运行的位置。但是互联网上的大多数解决方案都指向我使用布尔标志来控制线程的执行,如果我想停止线程然后将布尔变量设置为false。

但是如果runnable中的任务是一个LONG线性任务,这意味着任务不重复怎么办?在这种情况下,创建一个'而不是那么容易。循环以涵盖整个任务块。

使用Thread.stop非常流行,但警告"已弃用"使用起来似乎很危险。我已经阅读了这篇文章 Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?

但我无法理解

  

如果以前受这些监视器保护的任何对象都在   一个不一致的状态,其他线程现在可以查看这些对象   不一致的状态。据说这些物体已被损坏。

"不一致状态"意思?如果有人能解释一下,我很感激。

我想将我的问题扩展到更低级别的视图,比如JVM中的i = i + 1;(也许是汇编语言),也许这个Java语句将被分成几个较小的指令,例如像{{ 1}}(这是一个例子!我完全不懂汇编语言!)

现在,如果我们调用thread.stop,实际上它会停在哪里?线程是否会在COMPLETED Java语句之后停止,或者可能位于"汇编语言的中间"?如果答案是第二个,可能是我们说的原因

  

据说这些物品已被损坏。

好的,我的问题有点困惑,希望有人能理解和解释。提前谢谢。

5 个答案:

答案 0 :(得分:5)

“受损对象”是一个高级概念,它不会发生在JVM级别。程序员通过使用锁保护关键部分来设计他的类,并考虑到线程安全。他的班级是一个不变的,每个关键部分要么全部运行,要么根本不运行。当你stop一个线程时,一个关键部分可能在中间被中断,从而破坏了不变量。此时对象已损坏

停止一个线程隐藏了更多的危险,比如没有执行清理,没有释放获得的资源等。如果一个线程没有放弃它正在做的事情,就没有办法让它停止而不会损害整个应用程序。

实际上,只要有人需要运行可能需要强制中止的外来代码,就必须在单独的进程中完成,因为杀死进程至少会执行操作系统级别的清理和能够更好地控制损害。

答案 1 :(得分:3)

“不一致状态”表示应用程序关心的数据状态,通过使用锁/监视器等使应用程序具有线程安全性来说明您的应用程序逻辑已经过精心制作。

想象一下,你有这个简单的方法:

public synchronized void doSomething() 
{
      count++;
      average = count/total;
}

此方法与其他方法同步,因为多个线程正在使用此对象。 也许有一个

public synchronized AverageAndCount getMeasurement() 
{
   return new AverageAndCount(average, count);
}

这确保线程不能读取不完整的测量值,即当前测量值是否在例如内部计算的过程中。 doSomething(),getMeasurement()将阻塞/等待,直到完成。

现在,假设doSomething在一个线程中运行,并在该线程上调用.stop()

因此线程可能会在执行count++;之后立即停止,持有的监视器将被解锁并且方法终止并且average = count/total;不会被执行,

这意味着数据现在不一致。之后调用getMeasurement()的任何人现在都会获得不一致的数据。

另请注意,此时,无论是在java语句级别还是在较低级别,都不是非常相关,数据可能处于不一致的状态,在任何情况下都无法解释。

答案 2 :(得分:2)

我不是专家,但这就是我的想法。 如果使用Thread.stop(),则会导致ThreadDeath异常,从而导致释放所有监视器。 因为你引发了异常,所以你会对事物的状态施加不自然的行为。

依赖这些监视器的其他线程可能会因为不期望而进入不一致的情况。而且我不认为你甚至可以预期显示器会发布命令。

答案 3 :(得分:2)

我认为关注的是线程可能位于同步块的中间,对对象的成员执行多步更新。如果线程突然停止,则会发生一些更新但不会发生其他更新,现在对象的状态可能会使其无法使用。

我怀疑ThreadDeath处理会释放Lock支持的AbstractQueuedSynchronizer,这可能会使应用程序在路径上陷入一种僵局。

在您的长序列代码中的任何逻辑点,您只需添加:

if (Thread.interrupted())  {
    throw new InterruptedException();
}

...如果确定在执行长时间运行任务的Thread.interupt()上调用了Thread,这将在此时退出执行。

答案 4 :(得分:-1)

停止线程的方法并不清楚。每当run()方法完成或发生任何异常然后线程停止时,实际上都不推荐使用stop()方法。使用boolean flag变量.Bydefault“false”