4.线程中断

总结

  • 通过interrupt设置线程的中断标志位,并不能直接终止该线程,而是被中断的线程根据中断状态自行处理。
  • isInterrupted和interrupted都是检测线程是否被中断,区别在于isInterrupted可判断线程的中断情况,interrupted只能判断执行当前代码的线程的中断情况,后者会重置线程标志位为false。

1.线程中断三个关键方法

1.1 void interrupt()

中断线程。线程B调用线程A的interrupt方法,设置中断标志位为true后,立即返回。至于线程A什么时候被中断,需要线程A自行决定。例如,线程A因为调用了wait,sleep,join方法被阻塞挂起后,线程B调用了A的interrupt方法,线程A会在会在上述阻塞方法处抛出InterruptedException异常。

1.2 boolean isInterrupted()

检测线程是否被中断,返回true/false。

1.3 boolean interrupted()静态方法

检测当前线程是否被中断,返回true/false。若发现当前线程被中断,则会清除中断标志

内部实现:

return currentThread().isInterrupted(true);

2. 线程中断代码示例

2.1 使用isInterrupted优雅退出经典模式:

 public  void run(){
        try{
            while (!Thread.currentThread().isInterrupted() && ***){
                //do work
            }
        }catch (InterruptedException e){
            //thread was interrupted during sleep or wail or join
            e.printStackTrace();
        }finally {
            //clean resources
        }
    }

2.2 使用interrupt中断线程代码实例:

public  static void  main(String[] args) throws  InterruptedException{
        Thread threadOne = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    System.out.println("Thread one start sleep 20 s");
                    Thread.sleep(20000);
                    System.out.println("Thread one sleep over");
                }catch (InterruptedException e){
                    System.out.println("Thread one is interrupted while sleeping");
                    e.printStackTrace();
                    return;
                }
                System.out.println("Thread one leaving normaly");
            }
        });

        threadOne.start();
        Thread.sleep(1000);//主线程睡1秒

        threadOne.interrupt();//设置标志位中断线程

        threadOne.join();//让子线程运行结束
        System.out.println("main thread run over ...");

    }

输出:

Thread one start sleep 20 s
Thread one is interrupted while sleeping
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.evan.wj.ThreadTest$1.run(ThreadTest.java:10)
	at java.lang.Thread.run(Thread.java:748)
main thread run over ...

2.3 对比Interrupted和isInterrupted区别

代码实例1:

public  static void  main(String[] args) throws  InterruptedException{
        Thread threadOne = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true);
            }
        });

        threadOne.start();
        threadOne.interrupt();//设置中断标志

        System.out.println("第一次isInterrupted:"+threadOne.isInterrupted());//true
        System.out.println("第一次interrupted:"+threadOne.interrupted());//false
        System.out.println("第二次interrupted:"+threadOne.interrupted());//false
        System.out.println("第二次isInterrupted:"+threadOne.isInterrupted());//true

        System.out.println("main thread run over ...");

    }

输出:

第一次isInterrupted:true
第一次interrupted:false
第二次interrupted:false
第二次isInterrupted:true
main thread run over ...

解释:

第一个true,很简单,因为先设置了线程中断标志位,后判断是否被中断,返回true。

第二个false,interrupted调用的是currentThread.isInterrupted(true),因此表示主线程的线程中断标志位,当然为false。

第三个false,同第二次一样。

第四个true,由于isInterrupted并不会清除线程中断标志位,因此返回的依旧是true。

代码示例2:实践表明interrupted会清除中断标志位

 public  static void  main(String[] args) throws  InterruptedException{
        Thread threadOne = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().interrupted()){//清除了中断标志位
                }
                System.out.println("线程内isInterrupted:"+Thread.currentThread().isInterrupted());
            }
        });
        threadOne.start();

        threadOne.interrupt();//设置中断标志
        threadOne.join();
        System.out.println("main thread run over ...");
    }

输出:

线程内isInterrupted:false
main thread run over ...

解释:线程内部的interrupted重置了线程标志位,因此后面线程内的isInterrupted输出为false。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值