Java<优雅地理解线程interrupt、isInterrupted、interrupted>
来源:互联网 发布:常熟天下淘宝 编辑:程序博客网 时间:2024/06/05 14:14
1.什么是线程的中断
线程中断可以简单地理解为线程(Thread)有一个属性叫做“中断”,可以通过调用很多方法来查看该线程的这个属性的状态(TRUE、FALSE)
2.我调用这些方法的之后线程会立即中断么?
来看个例子:
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 50000; i++) { System.out.println(i); } }}
public class Run { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); //调用线程Mythread的实例的中断方法 thread.interrupt(); }}
在main线程挂起1秒之后,然后main线程给Mythread的实例(这里简写为MTH)发送了一个消息,告诉他“你把你的中断属性设置为TRUE”,但是MTH收到了这个消息之后只是单存地把这个自己的属性设置为TRUE,”然后并不中断自己”。
控制台打印1-49999:
49993499944999549996499974999849999Process finished with exit code 0
到这里答案已经很明显了,线程并不会因为简单地收到了其他线程的消息而中断自己
!!!如果要中断自己还要有附加操作
这些额外的操作是什么?
//Interrupted的经典使用代码 public void run(){ try{ .... while(!Thread.currentThread().isInterrupted()&& more work to do){ // do more work; } }catch(InterruptedException e){ // thread was interrupted during sleep or wait } finally{ // cleanup, if required } }
Thread.currentThread().isInterrupted()可以用来检测当前线程的中断属性
while循环有一个决定因素就是需要不停的检查自己的中断状态。当外部线程调用该线程的interrupt 时,使得中断状态置位即变为true。这是该线程将终止循环,不在执行循环中的do more work了。
3.interrupt()
这个方法是线程的一个内部方法,是由其他线程调用的,比如我在main方法中让main线程来调用MTH的interrupt()方法.
比如下面这个代码:
public class Run { public static void main(String[] args) throws InterruptedException { MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); //调用线程Mythread的实例的中断方法 thread.interrupt(); }}
这段代码会将MTH(如果你忘记了声明是MTH,网上翻)的中断属性为TRUE,仅此而已。
引申一下:
public static void main(String[] args) throws InterruptedException { Thread.currentThread().interrupt();}
如果我在main方法里调用了上面这行代码,会怎么样?
答案是:main线程的中断位会被设置为TRUE
4.isInterrupted()
这个方法主要用来获取当前线程的“中断”属性的状态,是TRUE还是FALSE。仅此而已。
套用上面的代码:
public static void main(String[] args) throws InterruptedException { Thread.currentThread().interrupt(); System.out.println("isInterrupted " + Thread.currentThread().isInterrupted());}
这里有一个点需要注意:在上面的代码中
Thread.currentThread()得到的是当前正在执行main方法的线程(也就是main线程)
控制台会输出什么?
TRUE
线程默认的中断位是FALSE,main线程调用了interrupt()之后,其中断位为TRUE,
isInterrupted()方法获取到的当然是TRUE
5.interrupted()
调用该线程的方法的中断位会被重置为FALSE
Thread.currentThread().interrupt(); System.out.println("isInterrupted " + Thread.currentThread().isInterrupted()); new MyThread().interrupted();//因为是Main线程执行这个方法,这个方法内部会把正在执行他的线程的中断标志位设置为false System.out.println("isInterrupted " + Thread.currentThread().isInterrupted());
以上的代码的执行的结果是:
isInterrupted trueisInterrupted false
原因很简单,Thread.currentThread().isInterrupted()方法执行之后main线程的中断位会被置为TRUE;
之后new MyThread().interrupted()执行,那么这行代码是谁在执行?当然是main线程在执行,也就是说执行interrupted()方法的线程是main。之前说了谁执行了interrupted()方法谁的中断位就会被置为FALSE,那现在main的中断位自然就会被置为FALSE了。
上面的话可能有点绕口,如果你不理解这段话,请看下面这个小例子:
public class DemoThread { static class MThread extends Thread { public MThread() { System.out.println("执行Mthread的线程是 :" + Thread.currentThread().getName()); } } public static void main(String[] args) { new MThread(); }}
这时候控制台的输出是:
执行Mthread的线程是 :main
因为是main线程创建了子线程,自然子线程的构造函数是被main线程调用的。
如果你还看不懂,请反复看,这很关键。
如果我要修改main线程的中断位,我只用通过new MyThread().interrupted()
方法么?答案是否定的,下面的代码也可做到
public class Run { public static void main(String[] args) throws InterruptedException { Thread.currentThread().interrupt();//false--->TRUE System.out.println("isInterrupted " + Thread.currentThread().isInterrupted()); Thread.interrupted();//true-->false System.out.println("isInterrupted " + Thread.currentThread().isInterrupted()); }}
* interrupted()的返回值:*
interrupted()会将标志位被自己置为之前的状态作为返回值然后,在置位标志位,看下面的代码:
public class Run { public static void main(String[] args) throws InterruptedException { Thread.currentThread().interrupt(); System.out.println(Thread.currentThread().interrupted()); System.out.println(Thread.currentThread().isInterrupted()); }}
控制台的输出是:
truefalse
因为Thread.currentThread().interrupt();将main线程置为了TRUE(FALSE->TRUE),然后System.out.println(Thread.currentThread().interrupted());将TRUE返回,然后在将中断位修改为FALSE,最后Thread.currentThread().isInterrupted()返回的就是FALSE了。
6.sleep() & interrupt()
如果线程MTH线程循环调用了sleep(10000),main线程想要让mth放弃Sleep状态,然后抛出异常
public class FindDiffInArray { static class BusyThread extends Thread { @Override public void run() { System.out.println("我是无相关线程"); } } static class MTH extends Thread { @Override public void run() { try { System.out.println("RUN begin"); Thread.sleep(2000000); System.out.println("RUN end"); } catch (InterruptedException e) { System.out.println("在沉睡中被停止 " + this.isInterrupted()); e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { MTH mth = new MTH(); mth.start(); Thread.sleep(200); mth.interrupt(); System.out.println(mth.isInterrupted()); }}
控制台的输出:
RUN beginjava.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at FindDiffInArray$MTH.run(FindDiffInArray.java:28)在沉睡中被停止 falsefalse
可以看到mth.interrupt();被执行之前mth一直在循环执行sleep()函数,接着是接收到中断信号,但是由于此时mth没有占用CPU时间片,没有占用CPU运行的线程是不可能给自己的中断状态置位的。这就会产生一个InterruptedException异常。
但是抛出异常之后,mth的中断位并没有被置为TRUE(从控制台的打印信息来看)
7.join() & interrupt().
当线程以join()等待其他线程结束时,当它被调用interrupt(),它与sleep()时一样, 会马上跳到catch块里.
注意,是对谁调用interrupt()方法,一定是调用被阻塞线程的interrupt方法.如在线程a中调用来线程t.join().则a会等t执行完后在执行t.join后的代码,当在线程b中调用来 a.interrupt()方法,则会抛出InterruptedException,当然join()也就被取消了。
8. wait() & interrupt()
线程A调用了wait()进入了等待状态,也可以用interrupt()取消.
不过这时候要小心锁定的问题.线程在进入等待区,会把锁定解除,当对等待中的线程调用interrupt()时,会先重新获取锁定,再抛出异常.在获取锁定之前,是无法抛出异常的.
- Java<优雅地理解线程interrupt、isInterrupted、interrupted>
- Java:interrupt()、interrupted()、isInterrupted()
- Java--interrupt(),interrupted(),isInterrupted()
- 线程中断,interrupt(),interrupted,isInterrupted()
- Java中的线程中断:interrupt()、interrupted()和isInterrupted
- 中断线程中 interrupt() isInterrupted interrupted
- 区分线程中的 interrupt() interrupted() isInterrupted()
- 07_线程停止(interrupt,interrupted,isInterrupted)
- 关于interrupt,interrupted和isInterrupted的理解
- Java多线程中的interrupt、interrupted、isInterrupted
- 【Java】interrupt、interrupted和isInterrupted的区别
- JAVA interrupt、interrupted和isInterrupted的区别
- Java多线程中interrupt interrupted isInterrupted
- java---interrupt、interrupted和isInterrupted的区别
- JAVA多线程之interrupt、interrupted、isInterrupted
- interrupt、interrupted 、isInterrupted 区别
- interrupt、isInterrupted、interrupted
- interrupt、interrupted 、isInterrupted 区别
- VMWare给macos虚拟机扩容方法
- socket....
- 用大数据思维做运维监控
- android studio 用ndk开发生成.h(头文件)时,出现找不到类的错误的解决方案
- VB-Image1.Picture、debug.print
- Java<优雅地理解线程interrupt、isInterrupted、interrupted>
- 数码管显示电路的设计
- 【Tools】dnw烧录配置
- java的NIO实现
- 关于卫片美化卫星图美化卫星图色差化问题的解决方案
- js:利用for循环,输出1-10所有数的平方和(即1-10的阶乘)
- 《数据结构学习与实验指导》4-2:树种统计
- 二叉树的路径和
- Android使用httpclient访问http