IT序号网

4.线程中断知识解答

itxm 2022年05月02日 编程语言 120 0
本文章主要介绍了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。
 


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

3.线程睡眠的Thread.sleep和让出cpu的Thread.yield静态方法知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。