线程中断机制(interrupt)

参考博文:Thread中interrupted()方法和isInterrupted()方法区别总结
廖雪峰的参考博文,最靠谱的做法

首先讲 interrupt() 方法:

interrupt()方法只是改变中断状态,不会中断一个正在运行的线程。需要用户自己去监视线程的状态为并做处理。

  1. interrupt 中断操作时,非自身打断需要先检测是否有中断权限,这由jvm的安全机制配置;

  2. 如果线程处于sleep, wait, join 等状态,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常;

  3. 如果线程处于I/O阻塞状态,将会抛ClosedByInterruptException(IOException的子类)异常;

  4. 如果线程在Selector上被阻塞,select方法将立即返回;

  5. 如果非以上情况,将直接标记 interrupt 状态;

    注意:interrupt 操作不会打断所有阻塞,只有上述阻塞情况才在jvm的打断范围内,如处于锁阻塞的线程,不会受 interrupt中断;

interrupted()和isInterrupted()方法说明

isInterrupted(),用来判断当前线程的中断状态(true or false)。
interrupted()是个Thread的static方法,内部调用了isInterrupted()方法,所以他首先会判断线程是否处于中断状态,其次他还可以用来恢复中断状态。
下面是源码说明:

  public boolean isInterrupted() {
        return isInterrupted(ClearInterrupted:false); //表示并不会重置中断标志位。
    }
public static boolean interrupted() {
        return currentThread().isInterrupted(ClearInterrupted:true);  //表示会重置中断标志位
    }

上面两个方法调用的方法如下:
作用是:测试某个线程是否被中断。中断状态将根据传递的clear的值重置或不重置----所以有两个功能;
1.首先返回的是线程是否被中断,
2.中断状态是否被重置取决于传入的值。

 /**
     * Tests if some Thread has been interrupted.  The interrupted state
     * is reset or not based on the value of ClearInterrupted that is
     * passed.
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

测试

阻塞情况下中断,抛出异常后线程恢复非中断状态,即 interrupted = false

public class ThreadTest {
    
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Task("1"));
        t.start();
        t.interrupt();
    }

    static class Task implements Runnable{
        String name;
        
        public Task(String name) {
            this.name = name;
        }
        
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("thread has been interrupt!");
            }
            System.out.println("isInterrupted: " + Thread.currentThread().isInterrupted());
            System.out.println("task " + name + " is over");
        }
    }
}

输出:

thread has been interrupt!
isInterrupted: false
task 1 is over

调用Thread.interrupted() 方法后线程恢复非中断状态

public class ThreadTest {
    
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Task("1"));
        t.start();
        t.interrupt();
    }

    static class Task implements Runnable{
        String name;
        
        public Task(String name) {
            this.name = name;
        }
        
        @Override
        public void run() {
            System.out.println("first :" + Thread.interrupted());
            System.out.println("second:" + Thread.interrupted());
            System.out.println("task " + name + " is over");
        }
    }
}

输出结果

first :true
second:false
task 1 is over

总结

所以想要中断一个线程:需要堵塞状态(sleep(),wait(),join())+线程中断标志(interrupt())两者配合使用,那么该线程将抛出一个 InterruptedException中断异常(该线程必须事先预备好处理此异常),从而提早地终结被阻塞状态。如果线程没有被阻塞,这时调用 interrupt()将不起作用,直到执行到wait(),sleep(),join()时,才马上会抛出 InterruptedException。
无论是先中断还是先阻塞最后都能达到停止线程的目的----------异常中断法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值