Java Thread.stop() - 已弃用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16504140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Thread.stop() - deprecated
提问by
Why is Thread.stop()
deprecated in Java? On their website, I see the following:
为什么Thread.stop()
在 Java 中被弃用?在他们的网站上,我看到以下内容:
Why is
Thread.stop
deprecated?Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the
ThreadDeath
exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions,ThreadDeath
kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
为什么被
Thread.stop
弃用?因为它本质上是不安全的。停止线程会使其解锁所有已锁定的监视器。(当
ThreadDeath
异常沿堆栈向上传播时,监视器被解锁。)如果以前受这些监视器保护的任何对象处于不一致状态,则其他线程现在可以查看处于不一致状态的这些对象。据说此类物品已损坏。当线程对损坏的对象进行操作时,可能会导致任意行为。这种行为可能很微妙且难以察觉,也可能很明显。与其他未经检查的异常不同,ThreadDeath
静默杀死线程;因此,用户没有警告他的程序可能已损坏。在实际损坏发生后的任何时间,甚至数小时或数天后,损坏都可能出现。
I don't understand what they mean by "monitors". Regardless, my question is if Thread.stop()
should not be called then how should a Java thread be stopped?
我不明白他们所说的“监视器”是什么意思。无论如何,我的问题是如果Thread.stop()
不应该被调用,那么 Java 线程应该如何停止?
采纳答案by goblinjuice
You asked:
你问:
My question is if theres no way to stop a thread in Java then how to stop a thread?
我的问题是,如果在 Java 中无法停止线程,那么如何停止线程?
The Answer: In Java there's no clean, quick or reliable way to stop a thread.
答案:在 Java 中没有干净、快速或可靠的方法来停止线程。
Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?
线程终止并不是那么简单。一个正在运行的线程,通常被许多作者称为轻量级进程,拥有自己的堆栈并且是自己命运的主人(守护进程就是这样)。它可能拥有文件和套接字。它可能持有锁。突然终止并不总是那么容易:如果线程正在写入文件并在完成写入之前被终止,则可能会出现不可预测的后果。或者当线程被击中头部时,线程持有的监视器锁呢?
Instead, Threads rely on a cooperativemechanism called Interruption. This means that Threads could only signalother threads to stop, not force them to stop.
相反,线程依赖于称为Interruption的协作机制。这意味着线程只能通知其他线程停止,而不能强制它们停止。
To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That's all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.
为了停止 Java 中的线程,我们依赖一种称为中断的协作机制。这个概念非常简单。为了停止一个线程,我们所能做的就是向它传递一个信号,也就是中断它,请求线程在下一个可用的机会停止它自己。就这样。不知道接收者线程可能对信号做什么:它甚至可能不会去检查信号;甚至更糟的是忽略它。
Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/
回答by Harshal Pandya
The right way is to use a join. Instead of prematurely stopping the execution of a thread, join will wait for the thread to finish execution before moving to the next statement.
正确的方法是使用连接。join 不会过早地停止线程的执行,而是在移动到下一条语句之前等待线程完成执行。
Thread exampleThread = new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//handle the exception
}
}
};
exampleThread.start();
exampleThread.join();
Here exampleThread.join() will wait until exampleThread is done executing before moving to the next statement. However, the onus of making sure that the thread does finish execution is on the programmer. In essence there is no way to stop a thread but if you design it right you should not need to stop the thread.
这里 exampleThread.join() 将等待直到 exampleThread 执行完成,然后再移动到下一条语句。但是,确保线程完成执行的责任在于程序员。本质上没有办法停止线程,但如果你设计得当,你就不需要停止线程。
回答by Tinki
When your thread handles interrupts correctly, it should be possible to instantly terminate it with use of ExecutorService
interface. According to Oracle documentation, ExecutorService.shutdownNow()
method, attempts to stop all actively executing tasks without waiting for their termination. There are however no guarantees beyond best-effort attempts to stop them. Here is some sample code:
当您的线程正确处理中断时,应该可以使用ExecutorService
接口立即终止它。根据 Oracle 文档ExecutorService.shutdownNow()
方法,尝试停止所有正在执行的任务而不等待它们终止。然而,除了尽最大努力阻止它们之外,没有任何保证。下面是一些示例代码:
class MyThread implements Runnable{
@Override
public void run() {
for (int i = 1; i < 10000000; i++)
try {
System.out.println(i + " ThreadID: " + Thread.currentThread().getId());
if (Thread.interrupted())
throw new InterruptedException();
} catch (InterruptedException e) {
return;
}
}
}
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.shutdownNow();
Without termination each thread should print message to console 10000000 times. executor.shutdownNow()
method instantly stops all three threads.
在不终止的情况下,每个线程应该将消息打印到控制台 10000000 次。executor.shutdownNow()
方法立即停止所有三个线程。
回答by Akhil Patro
From https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:
从https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:
Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized ).
大多数使用 stop 的代码应该替换为简单地修改一些变量以指示目标线程应该停止运行的代码。目标线程应该定期检查这个变量,如果变量表明它要停止运行,则以有序的方式从它的 run 方法返回。为确保停止请求的及时通信,变量必须是 volatile(或对变量的访问必须是同步的)。
回答by Alessandro Roaro
The logic to stop the thread should be handled in your implementation of the thread, so that you are sure that everything goes the way you want.
For example, you could create a cancel()
method that changes the state of the thread, which is checked cyclically. Like this:
停止线程的逻辑应该在您的线程实现中处理,以便您确保一切都按您想要的方式进行。例如,您可以创建一个cancel()
更改线程状态的方法,该方法会被循环检查。像这样:
class StoppableThread implements Runnable {
boolean isCancelled = false;
public void run() {
while (!isCancelled) {
System.out.println("Thread is running with all its might!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void cancel () {
isCancelled = true;
}
}