java-Thread.stop()-已弃用
为什么在Java中不推荐使用Thread.stop()? 在他们的网站上,我看到以下内容:
为什么不建议使用Thread.stop()?
因为它本质上是不安全的。 停止线程会使它解锁它已锁定的所有监视器。 (当Thread.stop()异常在堆栈中传播时,监视器将被解锁。)如果先前受这些监视器保护的任何对象处于不一致状态,则其他线程现在可以以不一致状态查看这些对象。 据说这些物体已损坏。 当线程对损坏的对象进行操作时,可能会导致任意行为。 此行为可能是微妙的,难以检测,或者可能是明显的。 与其他未检查的异常不同,ThreadDeath静默杀死线程; 因此,用户没有警告其程序可能已损坏。 在实际损坏发生后的任何时间,甚至未来数小时或数天,腐败都会显现出来。
我不明白“监视者”的含义。 无论如何,我的问题是,如果不应调用Thread.stop(),那么应该如何停止Java线程呢?
4个解决方案
39 votes
你问:
我的问题是,如果没有办法在Java中停止线程,那么如何停止线程?
答案:在Java中,没有干净,快速或可靠的方式来停止线程。
线程终止不是那么简单。 一个运行线程,通常被许多作者称为轻量级进程,它具有自己的堆栈,并且是自己命运的掌握者(守护程序就是这样)。 它可能拥有文件和套接字。 它可能会锁住。 突然终止并不总是那么容易:如果线程处于写入文件的中间,并且在完成写入之前被杀死,则可能会导致无法预料的后果。 或当头部中弹时,由线程保持的监视器锁又如何呢?
相反,线程依赖于称为中断的协作机制。 这意味着线程只能发信号通知其他线程停止,而不能强迫它们停止。
为了停止Java中的线程,我们依赖于一种称为中断的合作机制。 这个概念很简单。 要停止线程,我们所能做的就是向它传递一个信号,也就是打断它,要求线程在下一个可用的机会停止自身。 就这样。 没有告诉接收者线程如何处理信号:甚至可能不费心去检查信号。 甚至更糟的是忽略它。
来源:[https://codeahoy.com/java/How-To-Stop-Threads-Safely/]
goblinjuice answered 2020-08-04T21:33:07Z
8 votes
正确的方法是使用联接。 join不会过早地停止线程的执行,而将在移动到下一条语句之前等待线程完成执行。
Thread exampleThread = new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//handle the exception
}
}
};
exampleThread.start();
exampleThread.join();
在这里exampleThread.join()将等待exampleThread完成执行,然后再移至下一条语句。 但是,确保线程确实完成执行的责任在于程序员。从本质上讲,没有任何方法可以停止线程,但是如果设计正确,则无需停止线程。
Harshal Pandya answered 2020-08-04T21:33:32Z
7 votes
当线程正确处理中断时,应该可以使用executor.shutdownNow()接口立即将其终止。 根据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();
在不终止的情况下,每个线程应向控制台打印消息10000000次。 executor.shutdownNow()方法立即停止所有三个线程。
Tinki answered 2020-08-04T21:33:57Z
3 votes
从[https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:]
stop的大多数用法应由仅修改某些变量以指示目标线程应停止运行的代码代替。 目标线程应定期检查此变量,如果该变量指示要停止运行,则应有序地从其运行方法返回。 为了确保及时传达停止请求,变量必须是易失性的(或对变量的访问必须同步 )。
Akhil Patro answered 2020-08-04T21:34:22Z