上一章节中,我们对线程终止stop方法进行了讲解,stop终止线程的方法已经被丢弃,原因是线程的终止太暴力,会导致不必要的数据错误,所以stop方法在不自信的情况下,慎用慎用。。。。同时,也提供了较为完善的终止方案了。
本节就来学习线程中断 interrupt() 方法的使用:
一、先来看看源码:
public void interrupt() {
if (this != currentThread()) {
this.checkAccess();
}
Object var1 = this.blockerLock;
synchronized (this.blockerLock) {
Interruptible var2 = this.blocker;
if (var2 != null) {
this.interrupt0();
var2.interrupt(this);
return;
}
}
this.interrupt0();
}
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
return this.isInterrupted(false);
}
可以看出目前跟中断相关的有三个方法,分别是:
- interrupt(): 实例方法。它通知目标线程中断,也就是设置中断标志位(中断标志位表示当前线程已经被中断了)。
- isInterrupted():实例方法。用来判断当前线程是否有被中断(通过检查中断标志位)
- interrupted():静态方法。用来判断当前线程的中断状态,并清除当前线程的中断标志为状态。
二、我们来看看这些例子加理解:
栗子一:只使用interrupt()方法:
public class Interrupt_demo {
/**
* 例子1:
* 只使用interrupt方法
* @author fei
*
*/
public static class Interrupt_demo1 extends Thread{
@Override
public void run() {
System.out.println("线程"+Thread.currentThread().getName()+"在运行~~~~");
Thread.yield();
}
}
public static void main(String[] args) {
//创建10条线程
for (int i = 0; i < 10; i++) {
Thread thread=new Interrupt_demo1();
thread.start();
//如果是偶数,那么就中断
if (i%2==0) {
thread.interrupt();
}
}
}
}
创建10条线程,当偶数次的时候,中断该线程的执行,打印出该信息:
明显看到,就算中断了,也一样会执行10条线程。说明单单使用这个interrupt()方法是没有什么效果的。
栗子二:使用interrupt()配合isInterrupted()方法:
package stop_demo;
public class Interrupt_demo {
/**
* 例子1:
* 只使用interrupt方法
* @author fei
*
*/
public static class Interrupt_demo1 extends Thread{
@Override
public void run() {
//相对栗一添加对线程是否中断进行判断
if (Thread.currentThread().isInterrupted()) {
System.out.println("线程"+Thread.currentThread().getName()+"已被中断!!");
return;
}
System.out.println("线程"+Thread.currentThread().getName()+"在运行~~~~");
Thread.yield();
}
}
public static void main(String[] args) {
//创建10条线程
for (int i = 0; i < 10; i++) {
Thread thread=new Interrupt_demo1();
thread.start();
//如果是偶数,那么就中断
if (i%2==0) {
thread.interrupt();
}
}
}
}
运行后输出:
可以看到,使用interrupt()配合isInterrupted()方法是可以达到中断线程的目的的,这就理解interrupt()方法设置标志位的含义了。同时也可以看出,isInterrupted()方法实际上和上一篇文章stopThread()方法类似,但是isInterrupted()更为好用,因为isInterrupted()可以用在循环体中,有wait和sleep操作的线程中。
栗子三:三个方法配合使用
package stop_demo;
public class Interrupt_demo {
/**
* 例子1:
* 只使用interrupt方法
* @author fei
*
*/
public static class Interrupt_demo1 extends Thread{
@Override
public void run() {
if (Thread.interrupted()) {
System.out.println("线程"+Thread.currentThread().getName()+"判断为中断,但已经清除中断");
//看是否进入该判断,如果不进入那么证明中断已经清除了
if (Thread.currentThread().isInterrupted()) {
System.out.println("线程"+Thread.currentThread().getName()+"已被中断!!");
return;
}
}
System.out.println("线程"+Thread.currentThread().getName()+"在运行~~~~");
Thread.yield();
}
}
public static void main(String[] args) {
//创建10条线程
for (int i = 0; i < 10; i++) {
Thread thread=new Interrupt_demo1();
thread.start();
//如果是偶数,那么就中断
if (i%2==0) {
thread.interrupt();
}
}
}
}
运行后输出:
可以看到,使用静态方法判断中断线程,清除后,该线程就不是中断状态了,所以
if (Thread.currentThread().isInterrupted()) {
System.out.println("线程"+Thread.currentThread().getName()+"已被中断!!");
return;
}
该方法就不会执行了。