“嗨,阿米戈!

“一切新事物都只是我们忘记的旧事物。今天我将讨论停止线程。我希望你已经忘记了 interrupt() 方法是如何工作的。”

“是的,艾莉,我完全忘记了。”

“好,那我提醒你。”

“在 Java 中,如果有人想停止正在运行的线程,他可以向线程发出信号。为此,您需要将 Thread 对象的隐藏变量 isInterrupted 设置true。”

“每个Thread都有一个interrupt()方法,用来设置这个标志。当调用interrupt ()方法时, Thread对象内部的isInterrupted变量被设置为true。”

“并且当在线程上调用 Thread.sleep() 或 join() 方法时,该方法检查是否为当前线程设置了 isInterrupted 标志。如果设置了该标志(变量 isInterrupted 等于 true),方法抛出一个InterruptedException。”

“在这里,我提醒你一个古老的例子:”

代码 描述
class Clock implements Runnable
{
public void run()
{
Thread current = Thread.currentThread();

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tik");
}
}
}
Clock 的 run 方法获取当前线程的 Thread 对象。

只要当前线程的 isInterrupt 变量为 false,Clock 类就会每秒将单词“Tick”写入控制台一次。

当 isInterrupt 变为真时,run 方法终止。

public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
clockThread.interrupt();
}
主线程启动一个应该永远运行的子线程(时钟)。

等待 10 秒 ,调用中断方法取消任务。

主线程完成它的工作。

时钟线程完成它的工作。

“这里我们使用sleep方法作为run方法中无限循环的一部分。在循环中,自动检查isInterrupt变量。如果线程调用sleep方法,该方法首先检查该线程的isInterrupt是否为真(一个调用 sleep 方法的方法)。如果它是真的,那么该方法将不会睡眠。相反,它会抛出一个InterruptedException。”

“但在这个例子中,我们不断地检查循环条件中的 isInterrupted 变量。”

“我记得有一些我们不能使用这种方法的原因。你能提醒我一下吗?”

首先run方法并不总是有一个循环。该方法可能只包含对其他方法的几十次调用。在这种情况下,您必须在每个方法调用之前添加一个 isInterrupted 检查。”

其次,一些涉及许多不同动作的方法可能需要很长时间才能执行。”

第三,抛出异常不会取代 isInterrupted 检查。这只是一个方便的添加。抛出的异常让您可以快速将调用堆栈展开回 run方法本身。”

第四,睡眠方法用得很多。事实证明,这个有用的方法通过隐式检查得到了增强,同样有用。就 好像没有人专门添加检查一样,但它确实存在。 当你这样做时,这是非常有价值的正在使用别人的代码,你不能自己添加检查。”

第五,额外的检查不会降低性能。调用睡眠方法意味着线程不应该做任何事情(除了睡眠),所以额外的工作不会打扰任何人。”

“这正是你之前所说的。”

“那你的说法呢,«没有人能保证一个线程会被停止。只有一个线程可以自己停止。 »你能解释一下吗?”

“当然。”

“以前,在 Java 的早期版本中,线程有一个 stop() 方法。当你调用它时,JVM 实际上停止了线程。但是如果一个线程正在 JVM 之外做一些事情(例如,写入文件或调用OS函数)这样中断时,中断造成了很多问题,比如文件未关闭,系统资源未释放等。”

” Java的创建者大会决定取消强制停止线程的方法。现在我们所能做的就是设置某个标志(isInterrupted)并希望线程代码编写正确,以便处理这个标志。这个标志就像一个标语,上面写着:‘线程,请停止。这非常重要!’。但它是否停止是它自己的事。”

“但是 InterruptedException 呢?”

“如果在这个线程上运行的代码有一堆 try-catch 块怎么办?即使某处发生 InterruptedException,也绝对不能保证某些 try-catch 不会捕获它并忘记它。所以不能保证线程将停止。”

“另一件事是线程已经被认为是相当低级的编程。但我下次会告诉你。”

“你不是艾莉——你是山鲁佐德!”

“那么,阿米戈!这节课都讲清楚了吗?”

“是的。”

“好的。”