interrupt()
来通知,而不是强制。sleep()/wait()
等会响应中断的方法。
1.1 线程未处理中断:/**
* 正确停止线程---run()方法内没有sleep()或者wait()方法-未处理中断信号
*
* @author futao
* @date 2020/6/6
*/
public class StopThreadWithoutSleepWait implements Runnable {
@Override
public void run() {
unHandleInterrupt();
}
/**
* 未处理中断
*/
public void unHandleInterrupt() {
int num = 0;
//打印最大整数一半的范围内10000的倍数
while (num <= Integer.MAX_VALUE / 2) {
if (num % 10000 == 0) {
System.out.println(num + "是10000倍数");
}
++num;
}
System.out.println("任务执行完毕");
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new StopThreadWithoutSleepWait());
//启动线程
thread.start();
//增加子线程处于运行状态的可能性
Thread.sleep(500L);
//尝试中断子线程
thread.interrupt();
}
}
1.2 对程序进行改进:响应中断。
Thread.currentThread().isInterrupted()
),如果未被中断才继续执行,被中断则跳出while循环。package com.futao.learn.threads.c_如何停止线程;
/**
* 正确停止线程---run()方法内没有sleep()或者wait()方法
*
* @author futao
* @date 2020/6/6
*/
public class StopThreadWithoutSleepWait implements Runnable {
@Override
public void run() {
handleInterrupt();
}
/**
* 响应中断
*/
public void handleInterrupt() {
int num = 0;
//加入线程未被中断的条件
while (!Thread.currentThread().isInterrupted() && num <= Integer.MAX_VALUE / 2) {
if (num % 10000 == 0) {
System.out.println(num + "是10000倍数");
}
++num;
}
System.out.println("任务执行完毕");
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new StopThreadWithoutSleepWait());
//启动线程
thread.start();
//增加子线程处于运行状态的可能性
Thread.sleep(500L);
//尝试中断子线程
thread.interrupt();
}
}
sleep()/wait()
等会响应中断的方法。(响应中断的方法会抛出InterruptedException
)
2.1 sleep()
在while循环外/**
* 中断线程-run()方法中有sleep()或者wait()方法
*
* @author futao
* @date 2020/6/6
*/
public class StopThreadWithSleep {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
int num = 0;
while (!Thread.currentThread().isInterrupted() && num <= 300) {
if (num % 100 == 0) {
System.out.println(num + "是100的整数倍");
}
++num;
}
try {
//sleep()方法会响应中断,且响应中断的方式为抛出InterruptException异常--- sleep interrupted
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行完毕");
});
//启动线程
thread.start();
//等待while循环执行完毕
Thread.sleep(200L);
//当线程处于sleep()状态时进行中断
thread.interrupt();
}
}
sleep()
方法,此时进行中断,sleep()
方法响应该中断,抛出InterruptedException
,打印异常堆栈。2.2 无法停止的线程:sleep()方法在while循环内。
/**
* 3. 无法停止的线程
*
* @author futao
* @date 2020/6/6
*/
public class CantStopThread {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
int num = 1;
while (num <= 1000 && !Thread.currentThread().isInterrupted()) {
if (num % 2 == 0) {
System.out.println(num + "是2的整数倍");
}
++num;
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程执行完毕");
});
//启动线程
thread.start();
//主线程休眠500毫秒
Thread.sleep(500L);
//中断线程
thread.interrupt();
}
}
InterruptedException
异常被抛出后,线程的中断状态将被清除。Object.wait()
的方法描述。/**
* 正确停止线程的方式1-抛出中断
* 优先在方法签名中抛出该异常
*
* @author futao
* @date 2020/6/6
*/
public class RightWayToStopThread implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("running...");
try {
throwInMethod();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("响应中断,跳出循环,停止线程");
break;
}
}
}
/**
* 业务方法应该将中断异常抛出,将异常传递给上层--传递中断
*
* @throws InterruptedException
*/
private void throwInMethod() throws InterruptedException {
System.out.println("业务执行中.....");
Thread.sleep(2000L);
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new RightWayToStopThread());
thread.start();
Thread.sleep(1000L);
thread.interrupt();
}
}
Thread.currentThread().interrupt()
)/**
* 正确停止线程的方式2
* 恢复中断
*
* @author futao
* @date 2020/6/6
*/
public class RightWayToStopThreadReInterrupt implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("running...");
throwInMethod();
}
System.out.println("线程任务执行完毕");
}
private void throwInMethod() {
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
System.out.println("感知到中断请求。");
System.out.println("重新设置中断信号");
//尝试恢复中断
Thread.currentThread().interrupt();
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new RightWayToStopThreadReInterrupt());
thread.start();
Thread.sleep(1000L);
thread.interrupt();
}
}
/**
* 线程中断的相关方法
*
* @author futao
* @date 2020/6/7
*/
public class InterruptMethod {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程任务执行中...");
while (true) {
}
});
//启动线程
thread.start();
System.out.println(thread.isInterrupted());
//向线程发送中断信号
thread.interrupt();
System.out.println(thread.isInterrupted());
System.out.println(thread.isInterrupted());
System.out.println(Thread.interrupted());
System.out.println(thread.isInterrupted());
System.out.println(thread.interrupted());
System.out.println(thread.isInterrupted());
}
}
false
true
true
false
true
false
true
非中断状态
。线程状态状态为true
。thread.isInterrupted()
并不会清除线程的中断状态,所以多次调用,返回的结果一样,依旧为已中断
。Thread.interrupted()
判断的是执行这行代码的线程的中断状态。这里是主线程,所以为未中断。且该方法调用之后,会将执行该方法的线程的中断状态清除。Thread.interrupted()
清除的是执行代码的线程的中断状态,所以不印象子线程的中断状态,所以子线程的中断状态仍然为true。interrupted()
,返回的也是执行这段代码的线程的中断状态。此时为主线程,状态为未中断。interrupted()
并不会清除调用对象的线程中断状态,而是清除执行这段代码的线程的中断状态。所以子线程的中断状态不影响。static boolean interrupted()
清除的是执行者的中断状态呢?查看源码发现,静态方法static boolean interrupted()
会先获取到当前执行这段代码的线程,清除其中断状态,并返回中断状态。thread.interrupt()
给线程发送中断信号,设置线程thread
的中断状态为true。thread.isInterrupted()
判断线程thread
是否被中断。且不改变线程的中断状态Thread.interrupted()/thread.interrupted()
判断执行这行代码的线程的中断状态,并且清除其中断状态。private native boolean isInterrupted(boolean ClearInterrupted);
native方法,真正判断线程中断状态和清除中断状态的代码。thread.isInterrupted()
和Thread.interrupted()/thread.interrupted()
最终调用的都是这个方法。Thread.interrupted();
这行代码的线程的中断状态会被清除。run()
方法正常执行完毕。(可借助线程中断机制提前结束run()方法)stop()
,suspend()
和resume()
InputStream.read()
。处理这类问题的方式要视情况而定,大概思路是手动编写程序检测线程的中断状态,如果线程被中断,则手动调用例如InputStream.close()
方法来关闭流,实现停止线程。https://github.com/FutaoSmile/learn-thread/tree/master/src/main/java/com/futao/learn/threads/c_%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2%E7%BA%BF%E7%A8%8B
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有