Java基础-线程-线程的停止与中断
2021-01-31 本文已影响0人
HughJin
线程的停止/中断
由于使用stop方法停止线程非常暴力, 现已经列为不推荐使用的行列。
中断线程的方式是一种温和的方式。
中断线程的方法有:
-
interrupt()
:中断这个线程。Thread类成员方法
interrupt方法有两个作用:(1)将线程的中断状态设置为true(2)让被阻塞的线程抛出InterruptedException异常(同时中断状态为false)。
-
isInterrupted()
:测试这个线程是否被中断。 线程的中断状态不受此方法的影响。 -
public static boolean interrupted()
:测试当前线程是否中断。 该方法可以清除线程的中断状态 。
线程中断的解释
每个线程都有一个与之相关联的 Boolean 属性,用于表示线程的中断状态(interrupted status)。
中断状态初始时为 false;当另一个线程通过调用Thread.interrupt()
中断一个线程时,会出现以下两种情况之一。
- (1)如果那个线程在执行一个低级可中断阻塞方法,例如
Thread.sleep(), Thread.join()或 Object.wait()
,那么它将取消阻塞并抛出InterruptedException
。 - (2)否则,
interrupt()
只是设置线程的中断状态。在被中断线程中运行的代码以后可以轮询中断状态,看看它是否被请求停止正在做的事情。中断状态可以通过Thread.isInterrupted()
来读取,并且可以通过一个名为Thread.interrupted()
的操作读取和清除。
中断是一种协作机制。当一个线程中断另一个线程时,被中断的线程不一定要立即停止正在做的事情。相反,中断是礼貌地请求另一个线程在它愿意并且方便的时候停止它正在做的事情。
中断的协作特性所带来的一个好处是,它为安全地构造可取消活动提供更大的灵活性。我们很少希望一个活动立即停止;如果活动正在进行更新的时候被取消,那么程序数据结构可能处于不一致状态。中断允许一个可取消活动来清理正在进行的工作,恢复不变量,通知其他活动它要被取消,然后才终止。
用法:成员方法interrupt()
与成员isInterrupted()
结合使用。
interrupt(),isInterrupted(),interrupted() 代码测试
package com.thread.study;
public class ThreadInterrupted {
public static void main(String[] args) {
new Thread(() -> {
for (int i = 0; i < 20; i++) {
if (i == 10) {
Thread.currentThread().interrupt(); // 成员方法interrupt() Interrupted状态会变
}
System.out.println(Thread.currentThread().getName() + "Interrupted状态" + Thread.currentThread().isInterrupted() + ":" + i);
}
}, "张三").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
if (i == 10) {
Thread.interrupted(); // 静态方法interrupted() Interrupted状态不变
}
System.out.println(Thread.currentThread().getName() + "Interrupted状态" + Thread.currentThread().isInterrupted() + ":" + i);
}
}, "王五").start();
new Thread(() -> {
for (int i = 0; i < 20; i++) {
if (Thread.currentThread().isInterrupted()) {// 中断状态判断
System.err.println(Thread.currentThread().getName() + "执行结束!!!" + "此时的i为" + i);
break;
}
if (i == 10) {
Thread.currentThread().interrupt();//中断线程
}
}
}, "李四").start();
}
}
执行结果:
张三Interrupted状态false:0
王五Interrupted状态false:0
张三Interrupted状态false:1
王五Interrupted状态false:1
张三Interrupted状态false:2
王五Interrupted状态false:2
张三Interrupted状态false:3
王五Interrupted状态false:3
王五Interrupted状态false:4
王五Interrupted状态false:5
王五Interrupted状态false:6
王五Interrupted状态false:7
王五Interrupted状态false:8
王五Interrupted状态false:9
王五Interrupted状态false:10
王五Interrupted状态false:11
王五Interrupted状态false:12
王五Interrupted状态false:13
王五Interrupted状态false:14
王五Interrupted状态false:15
王五Interrupted状态false:16
王五Interrupted状态false:17
王五Interrupted状态false:18
王五Interrupted状态false:19
张三Interrupted状态false:4
张三Interrupted状态false:5
张三Interrupted状态false:6
张三Interrupted状态false:7
张三Interrupted状态false:8
张三Interrupted状态false:9
张三Interrupted状态true:10
张三Interrupted状态true:11
张三Interrupted状态true:12
张三Interrupted状态true:13
张三Interrupted状态true:14
张三Interrupted状态true:15
张三Interrupted状态true:16
张三Interrupted状态true:17
张三Interrupted状态true:18
张三Interrupted状态true:19
李四执行结束!!!此时的i为11
成员方法interrupt()与成员isInterrupted()结合使用
package com.thread.study;
public class ThreadInterrupt {
public static void main(String[] args) {
// 总结 成员方法interrupt()与成员isInterrupted()结合使用, 线程逻辑内
new Thread(() -> {
int number = 0;
// 记录程序开始的时间
Long start = System.currentTimeMillis();
while (true) {
// 每次执行一次结束的时间
Long end = System.currentTimeMillis();
// 获取时间差
long interval = end - start;
// 如果时间超过了2毫秒,那么我们就结束下载
if (interval >= 2) {
// 中断线程
Thread.currentThread().interrupt();
System.err.println("已下载" + number + "M,太慢了,不下载了");
} else if (number >= 500) {
System.out.println("文件下载完成");
// 中断线程
Thread.currentThread().interrupt();
} else {
number++;
}
if (Thread.currentThread().isInterrupted()) {
if (number >= 500) {
System.out.println("已下载" + number + "M,下载完啦");
} else {
System.err.println("已下载" + number + "M,不下载了");
}
return;
}
}
}, "下载线程").start();
// 总结 成员方法interrupt()与成员isInterrupted()结合使用, 线程逻辑外
Thread thread = new Thread(() -> {
int number = 0;
while (true) {
if (number >= 500) {
System.out.println("文件下载完成");
// 执行完毕
return;
} else {
number++;
}
if (Thread.currentThread().isInterrupted()) {
if (number >= 500) {
System.out.println("已下载" + number + "M,下载完啦");
} else {
// ... 断点续传操作
System.err.println("已下载" + number + "M,不下载了");
}
return;
}
}
}, "download线程");
thread.start();
thread.interrupt();//手动 中断线程
}
}
// 执行结果
已下载1M,不下载了
已下载148M,太慢了,不下载了
已下载148M,不下载了