CodeGym /课程 /Java 核心 /停止线程:官方版本

停止线程:官方版本

Java 核心
第 6 级 , 课程 9
可用

“你好,阿米戈!你必须承认,艾莉的 Cancel(取消)想法很棒。”

“是的。”

“实际上,Thread 类中存在一些类似的功能。只是变量不叫 isCancel。而被称为 isInterrupt。并且,用于停止线程的方法不是 cancel(),而是 interrupt()。”

“真的吗?”

“是的。我们来看一下:”

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

while (!current.isInterrupted())
{
Thread.sleep(1000);
System.out.println("Tick");
}
}
}
由于多个线程可以在同一 Clock 对象上调用 run 方法,因此我们为当前线程获取 Thread 对象

只要当前线程的 isInterrupt 变量为 false,Clock 类会每隔一秒向控制台写入一次词语“嘀嘀”。

isInterrupt 变为 true 时,run 方法终止。

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

Thread.sleep(10000);
clockThread.interrupt();
}
主线程启动应始终运行的子线程 (clock)。

等待 10 秒,然后通过调用 interrupt 方法取消任务。

主线程完成工作。

clock 线程结束工作。

而且,人们特别喜欢在 run 方法的无限循环中使用的 sleep 方法会自动检查 isInterrupt 变量。如果一个线程调用 sleep 方法,它将首先为该线程检查 isInterrupt 是否为 true。如果为 true,则方法不会进入休眠状态。相反,它会抛出一个 InterruptedException 异常。

“为什么会抛出异常?直接在循环中使用 isInterrupted() 而不是 isCancel() 会不会更好?”

首先run 方法并不总是包含循环。该方法可能只包含对其他方法的几十个调用。然后,你将必须在每个方法调用之前添加 isInterrupted 检查。”

其次,某个包含许多不同操作的方法可能需要很长时间才能执行完。”

第三,抛出异常不会替代 isInterrupted 检查。这只是一个方便的附加功能。抛出的异常允许你快速将调用堆栈回退到 run 方法本身。”

第四,sleep 方法的使用非常频繁。事实证明,这个有用的方法通过同样有用的隐式检查得到了增强。就像无人明确添加检查,但它确实存在。当你使用别人的代码而自己无法添加检查时,这是非常有用的。”

第五,附加检查不会降低性能。调用 sleep 方法意味着线程不会做任何事情(除了休眠),因此额外的工作不会困扰任何人。”

“那会引发激烈的争论。”

最后一点是:你的 run 方法可以调用别人的代码 — 你无权访问的代码(源代码和/或更改代码的权限)。它可能没有 isInterrupted 检查,并且可能使用‘try ... catch (Exception e)’来捕获所有异常。”

没有人可以保证线程将被停止。线程只能自行停止

评论 (12)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
云中桥 级别 41,China,China
27 五月 2023
day9
zzzz 级别 25,China,China
27 五月 2024
天才
Anonymous #10812327 级别 28,Changsha,China
23 三月 2022
如果为 true,则方法不会进入休眠状态。相反,它会抛出一个 InterruptedException 异常。 我不是很懂这句话。TRUE不会进入休眠,反之FALSE抛出异常一样不会休眠,那sleep如何进入休眠?
_約束- 级别 17,China,China
5 十月 2022
while里的条件是 (!current.isInterrupted()),如果isInterrupted为true那么while里的条件就是false,那当然就不进入循环了啊
Qin-1999 级别 22
19 一月 2024
是True不进入休眠。 这是一句话,然后是,相反(其实想说的是:情况相反的话,则会抛出异常),抛出异常就停了。
kqhasaki 级别 23,Daxi,Taiwan, Province of China
17 八月 2021
这里的例子里面,clock线程并没有结束。因为在向线程发出中断信号的时候,这个线程正在执行sleep()。这里由于收到了线程中断,所以isInterrupted会返回true,但是由于该线程抛出了InterruptedException异常,因此线程会马上被设置为非中断状态。如果你在catch块中没有处理异常,那么下一次循环开始条件检查时,线程仍然是非中断状态,因此会继续执行。 例子里面,我们可以在catch块里面加上:

current.interrupt();
a_a 级别 22
6 三月 2022
说得没错,但前提是try ... catch的范围仅仅是Thread.sleep(1000);那一句代码。如果try ... catch的范围是整个循环,线程收到中断信号后,会抛出InterruptedException,清除中断状态,跳出循环,然后自行停止。
Anonymous #10766052 级别 20,Shenzhen
7 七月 2021
clock 线程并未结束吧?
Kolania 级别 20,Baotou,China
2 十一月 2020
哪位大神给解释一下
TaoLu 级别 20,泾县,China
25 三月 2021
“首先,run 方法并不总是包含循环。该方法可能只包含对其他方法的几十个调用。然后,你将必须在每个方法调用之前添加 isInterrupted 检查。” “其次,某个包含许多不同操作的方法可能需要很长时间才能执行完。” “第三,抛出异常不会替代 isInterrupted 检查。这只是一个方便的附加功能。抛出的异常允许你快速将调用堆栈回退到 run 方法本身。” “第四,sleep 方法的使用非常频繁。事实证明,这个有用的方法通过同样有用的隐式检查得到了增强。就像无人明确添加检查,但它确实存在。当你使用别人的代码而自己无法添加检查时,这是非常有用的。” “第五,附加检查不会降低性能。调用 sleep 方法意味着线程不会做任何事情(除了休眠),因此额外的工作不会困扰任何人。” “那会引发激烈的争论。” “最后一点是:你的 run 方法可以调用别人的代码 — 你无权访问的代码(源代码和/或更改代码的权限)。它可能没有 isInterrupted 检查,并且可能使用‘try ... catch (Exception e)’来捕获所有异常。” 没有人可以保证线程将被停止。线程只能自行停止”
liu_yi_quan 级别 22,JiangXi,China
18 十二月 2021
你搁这搁这呢
momoshenchi 级别 22,Wenzhou,China
18 八月 2020
又看不懂了.