java 线程 interrupted_【Java】聊聊线程中断interrupt(),isInterrupted(),interrupted()三者区别...

本文深入探讨了Java中线程中断相关的方法interrupt(), isInterrupted(), interrupted()的区别。interrupt()用于设置线程中断标志,但不会立即停止线程;isInterrupted()检查中断状态而不改变它;interrupted()同样检查中断状态,但会清除该标志。通过示例代码解析了这些方法的使用和输出结果,帮助读者理解它们在多线程编程中的应用。" 103231916,7860581,图像增强:伪彩色与彩色变换实践,"['图像处理', '图像增强技术', '色彩空间转换']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首页

专栏

java

文章详情

0

聊聊线程中断interrupt(),isInterrupted(),interrupted()三者区别

108055.html小强大人发布于 今天 15:32

前言

Java多线程中的中断,大家应该不陌生。但是,Thread.java中的三个中断相关函数interrupt(),isInterrupted(),interrupted(),你都真正清楚它们之前的区别吗?今天就来聊聊这个话题。

区别

public void interrupt():中断线程,例如,当线程A运行时,线程B可以调用A.interrupt()方法,来设置线程A的中断标志为true,然后线程B立即返回。注意,这里仅仅是设置标志,线程A实际并没有被中断,它会继续往下执行。但是有一种情况,如果线程A调用了wait系列函数、join方法或者sleep方法而被阻塞挂起,这时候线程B调用A.interrupt()方法时,线程A会在调用wait/join/sleep方法处抛出InterruptedException异常而返回。

public boolean isInterrupted():检测当前线程是否被中断,如果是返回true,否返回false。

public static boolean interrupted():也是检测当前线程是否被中断,是返回true,否返回false,它与isInterrupted不同的是,如果被中断了,返回true的同时会清除中断标志(即重置中断标志为false),并且可以看到它是一个静态方法,可以直接Thread.interrupted()调用,上面2个是普通方法,需要拿到线程实例调用。

可以翻下三者的源码:

interrupt()

public void interrupt() {

if (this != Thread.currentThread())

checkAccess();

synchronized (blockerLock) {

Interruptible b = blocker;

if (b != null) {

interrupt0(); // Just to set the interrupt flag

b.interrupt(this);

return;

}

}

interrupt0();

}

isInterrupted()

public boolean isInterrupted() {

return isInterrupted(false);

}

interrupted()

public static boolean interrupted() {

return currentThread().isInterrupted(true);

}

这里的isInterrupted(boolean)是一个本地方法:

private native boolean isInterrupted(boolean ClearInterrupted);

可以看到,isInterrupted调用它时,传入的参数是false,表示不清除中断标志,而interrupted调用它时,传入的是true,表示要清除中断标志。

举例说明

上面的陈述可能有点抽象,没关系,我们通过一个例子来加深印象,请思考下面的代码依次输出什么结果?先不要往下翻答案哦!

public class InterruptDemo {

public static void main(String[] args) throws InterruptedException {

Thread threadOne = new Thread(() -> {

for (;;) {

// do nothing, just dead cycle

}

});

// 启动线程1

threadOne.start();

// (1)设置中断标志

threadOne.interrupt();

// (2)获取中断标志

System.out.println("isInterrupted: " + threadOne.isInterrupted());

// (3)获取中断标志并重置

System.out.println("isInterrupted: " + threadOne.interrupted());

// (4)获取中断标志并重置

System.out.println("isInterrupted: " + Thread.interrupted());

// (5)获取中断标志

System.out.println("isInterrupted: " + threadOne.isInterrupted());

// 主线程等待线程1执行完毕

threadOne.join();

System.out.println("main thread is over!");

}

}

———————-分割线——————–

输出结果是:

668d88d0a61edc8e7bbb82353acbd3ce.png

你答对了吗?是不是跟你预想的有点不同?别急,我们逐个分析下

第(1)步,主线程调用线程threadOne的interrupt()方法,此时线程threadOne的中断标志为true,因此第1个输出为true,这相信没什么疑问。

第(2)步,主线程调用线程threadOne的interrupted()方法,这步很容易让人误以为是判断线程threadOne是否被中断并且清除标志,但是这是个陷阱!看看interrupted()源码:

8e348d8002f8d9f5be603ffe51a5ddef.png

它是返回当前线程是否被中断,当前线程是主线程!并不是threadOne!因为threadOne.interrupted()这行代码是在主线程中执行的,所以当前线程是主线程,如果放在threadOne的run()方法里执行,那么当前线程就是threadOne,想明白了吗?回到主题,主线程此前并没有被中断,所以第2个输出false。

第(3)步,也是判断当前线程(主线程)是否被中断,很显然,第3个依然输出false。

第(4)步,判断线程threadOne是否被中断,由于threadOne先前的中断标志为true,并且isInterrupted()并不会清除中断标志,所以第4个输出依然为true。

结束语

本文讲解了interrupt(),isInterrupted(),interrupted()三者区别,如果不注意的话,这3者很容易混淆,希望通过本文,让大家更好地理解它们之间的区别,也可以在工作的使用过程中加深理解。最后附上一个线程利用中断机制优雅退出的伪代码,在工作中可以这么去用:

public void run() {

try {

while(!Thread.currentThread().isInterrupted() && condition not satisfied) {

// do work

}

} catch(InterruptedException e) {

// thread was interrupted while wait or sleep

} finally {

// cleanup work, if necessary

}

}

java

阅读 57更新于 今天 15:33

赞收藏

分享

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议

108055.html

小强大人

4声望

1粉丝

关注作者

0 条评论

得票时间

108055.html

提交评论

108055.html

小强大人

4声望

1粉丝

关注作者

宣传栏

前言

Java多线程中的中断,大家应该不陌生。但是,Thread.java中的三个中断相关函数interrupt(),isInterrupted(),interrupted(),你都真正清楚它们之前的区别吗?今天就来聊聊这个话题。

区别

public void interrupt():中断线程,例如,当线程A运行时,线程B可以调用A.interrupt()方法,来设置线程A的中断标志为true,然后线程B立即返回。注意,这里仅仅是设置标志,线程A实际并没有被中断,它会继续往下执行。但是有一种情况,如果线程A调用了wait系列函数、join方法或者sleep方法而被阻塞挂起,这时候线程B调用A.interrupt()方法时,线程A会在调用wait/join/sleep方法处抛出InterruptedException异常而返回。

public boolean isInterrupted():检测当前线程是否被中断,如果是返回true,否返回false。

public static boolean interrupted():也是检测当前线程是否被中断,是返回true,否返回false,它与isInterrupted不同的是,如果被中断了,返回true的同时会清除中断标志(即重置中断标志为false),并且可以看到它是一个静态方法,可以直接Thread.interrupted()调用,上面2个是普通方法,需要拿到线程实例调用。

可以翻下三者的源码:

interrupt()

public void interrupt() {

if (this != Thread.currentThread())

checkAccess();

synchronized (blockerLock) {

Interruptible b = blocker;

if (b != null) {

interrupt0(); // Just to set the interrupt flag

b.interrupt(this);

return;

}

}

interrupt0();

}

isInterrupted()

public boolean isInterrupted() {

return isInterrupted(false);

}

interrupted()

public static boolean interrupted() {

return currentThread().isInterrupted(true);

}

这里的isInterrupted(boolean)是一个本地方法:

private native boolean isInterrupted(boolean ClearInterrupted);

可以看到,isInterrupted调用它时,传入的参数是false,表示不清除中断标志,而interrupted调用它时,传入的是true,表示要清除中断标志。

举例说明

上面的陈述可能有点抽象,没关系,我们通过一个例子来加深印象,请思考下面的代码依次输出什么结果?先不要往下翻答案哦!

public class InterruptDemo {

public static void main(String[] args) throws InterruptedException {

Thread threadOne = new Thread(() -> {

for (;;) {

// do nothing, just dead cycle

}

});

// 启动线程1

threadOne.start();

// (1)设置中断标志

threadOne.interrupt();

// (2)获取中断标志

System.out.println("isInterrupted: " + threadOne.isInterrupted());

// (3)获取中断标志并重置

System.out.println("isInterrupted: " + threadOne.interrupted());

// (4)获取中断标志并重置

System.out.println("isInterrupted: " + Thread.interrupted());

// (5)获取中断标志

System.out.println("isInterrupted: " + threadOne.isInterrupted());

// 主线程等待线程1执行完毕

threadOne.join();

System.out.println("main thread is over!");

}

}

———————-分割线——————–

输出结果是:

668d88d0a61edc8e7bbb82353acbd3ce.png

你答对了吗?是不是跟你预想的有点不同?别急,我们逐个分析下

第(1)步,主线程调用线程threadOne的interrupt()方法,此时线程threadOne的中断标志为true,因此第1个输出为true,这相信没什么疑问。

第(2)步,主线程调用线程threadOne的interrupted()方法,这步很容易让人误以为是判断线程threadOne是否被中断并且清除标志,但是这是个陷阱!看看interrupted()源码:

8e348d8002f8d9f5be603ffe51a5ddef.png

它是返回当前线程是否被中断,当前线程是主线程!并不是threadOne!因为threadOne.interrupted()这行代码是在主线程中执行的,所以当前线程是主线程,如果放在threadOne的run()方法里执行,那么当前线程就是threadOne,想明白了吗?回到主题,主线程此前并没有被中断,所以第2个输出false。

第(3)步,也是判断当前线程(主线程)是否被中断,很显然,第3个依然输出false。

第(4)步,判断线程threadOne是否被中断,由于threadOne先前的中断标志为true,并且isInterrupted()并不会清除中断标志,所以第4个输出依然为true。

结束语

本文讲解了interrupt(),isInterrupted(),interrupted()三者区别,如果不注意的话,这3者很容易混淆,希望通过本文,让大家更好地理解它们之间的区别,也可以在工作的使用过程中加深理解。最后附上一个线程利用中断机制优雅退出的伪代码,在工作中可以这么去用:

public void run() {

try {

while(!Thread.currentThread().isInterrupted() && condition not satisfied) {

// do work

}

} catch(InterruptedException e) {

// thread was interrupted while wait or sleep

} finally {

// cleanup work, if necessary

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值