java多线程interrupt_Java多线程之interrupt()的深度研究

接下来说一下"interrupted()"和"isInterrupted()"两个方法的相同点和不同点。在这之前看一下源码中两个方法的代码,如下:

9fe6ef747aadfcc81e71a0798f26b64f.gif1 public static boolean interrupted() { 2     return currentThread().isInterrupted(true); 3     } 4 public boolean isInterrupted() { 5     return isInterrupted(false); 6     } 7  /** 8      * Tests if some Thread has been interrupted.  The interrupted state 9      * is reset or not based on the value of ClearInterrupted that is10      * passed.11      */12 private native boolean isInterrupted(boolean ClearInterrupted);

9fe6ef747aadfcc81e71a0798f26b64f.gif

相同点都是判断线程的interrupt status是否被设置,若被设置返回true,否则返回false.区别有两点:一:前者是static方法,调用者是current thread,而后者是普通方法,调用者是this current.二:它们其实都调用了Java中的一个native方法isInterrupted(boolean ClearInterrupted); 不同的是前者传入了参数true,后者传入了false.意义就是:前者将清除线程的interrupt state(®3),调用后者线程的interrupt state不受影响。

二:例子。

接下来看一个例子,这个例子说明了两个问题。1.调用interrupt()方法并不会中断一个正在运行的线程.2.若调用sleep()而使线程处于阻塞状态,这时调用interrupt()方法,会抛出InterruptedException,从而使线程提前结束阻塞状态,退出阻塞代码。如下:

9fe6ef747aadfcc81e71a0798f26b64f.gif1 package interrupt; 2  3 public class Main { 4     /** 5      * @param args 6      */ 7     public static void main(String[] args) { 8         Main main = new Main(); 9         Thread t = new Thread(main.runnable);10         System.out.println("mainmainmain");11         t.start();12         try {13             Thread.sleep(2000);14         } catch (InterruptedException e) {15             // TODO Auto-generated catch block16             e.printStackTrace();17         }18         t.interrupt();19     }20 21     Runnable runnable = new Runnable() {22         @Override23         public void run() {24             int i = 0;25             try {26                 while (i 

9fe6ef747aadfcc81e71a0798f26b64f.gif

运行结果:

9fe6ef747aadfcc81e71a0798f26b64f.gif1 mainmainmain2 03 14 25 java.lang.InterruptedException: sleep interrupted6     at java.lang.Thread.sleep(Native Method)7     at interrupt.Main$1.run(Main.java:27)8     at java.lang.Thread.run(Thread.java:619)

9fe6ef747aadfcc81e71a0798f26b64f.gif

三:分析下例子中的中断机制

1.为什么调用interrupt()并不能中断线程?

9fe6ef747aadfcc81e71a0798f26b64f.gif1 public void interrupt() { 2     if (this != Thread.currentThread()) 3         checkAccess(); 4  5     synchronized (blockerLock) { 6         Interruptible b = blocker; 7         if (b != null) { 8         interrupt0();        // Just to set the interrupt flag 9         b.interrupt();10         return;11         }12     }13     interrupt0();14     }

9fe6ef747aadfcc81e71a0798f26b64f.gif

如上是Java源码中的代码,由此我们看出问题的答案。线程的blocker字段(也就是interrupt status)默认是null(®1)。调用interrupt()方法时,只是运行了®2,并没有进入if语句,所以没调用真正执行中断的代码b.interrupt().

2.若调用sleep()而使线程处于阻塞状态,这时调用interrupt()方法,会抛出InterruptedException,从而使线程提前结束阻塞状态,退出阻塞代码。为什么?

5345d7bb5d049dbf25f7dc76bd0e7241.png

由上图可看出例子中30行代码铺好的异常其实是interrupt()抛出的,而不是sleep()抛出的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值