• Interrupt()这个方法是会给当前执行的线程发送一个中断的信号

  • interrupted() 与isInterrupted() 这两个的作用是一样的,那为什么要一个是静态方法一个非静态方法呢?

Demo

  • 定义一个线程假设他在做一些事情,他启动之后可能还没有真正的运行起来,直接输出打断是不太正确的所以简单的休眠一下。

  • 运行结果:

  • 没有中断前是false,打断后为true。

  • 线程一直运行的原因是:还没有捕获到线程被中断的信息,或者说通过线程被中断会抛出异常但是没有任何异常捕获的语句。
  • 那怎么做呢?先看下Api文档

  • 根据文档说要使用那几个方法后会捕获到InterruptedException异常,如果没有使用到呢?

  • 尝试在循环里面输出一下:

  • 运行结果:

  • 结果显示还是有这样的信号,并不是说只有在线程里面有那几个方法的时候他才会收到。

Interrupt源码

  • 如果不是当前线程自我中断,会先做一次权限检查。如果被中断的线程属于系统线程组(即JVM线程),checkAccess()方法会使用系统的System.getSecurityManager()来判断权限,如果权限不允许会抛出SecurityException。由于Java默认没有开启安全策略,此方法其实会跳过安全检查。

  • blockerLock 是他自己定义的一个锁

  • Interruptible b = blocker; 这个是怎么传的呢?
  • interrupt0(); 他是不管刚才读文档说的“有没有那三种类型的方法去调用,他都会被interrupt status去进行设置”
  • 所以说我们这边只是没有任何方法捕获到他的这个异常,才退不出来。

sleep()的打断方式

  • 改为:

  • 运行结果:

  • 收到打断信息,休眠状态被打断,线程收到信号之后,他还在运行,还在死循环里面。

wait()的打断方式

  • 已经看了interrupted() 与isInterrupted() 这两个方法,通过sleep的方式去打断他。

  • 接下里来看一下wait()的方式。

  • wait()是Object的一个方法,不是线程特有的方法,那怎么去做呢?

  • 使用wait()方法的时候必须给一个monitor,这个monitor必须是用synchronized去进行包装。

  • 运行结果:

  • 中断信号收到,同时也被捕获了,没有退出的原因是死循环任务没有完成。

  • 调用之前比较老的方法可以吗?

  • 确实是可以的,但是会有严重的问题,这个方法在很多版本以前就不让用了,建议千万不要使用。

  • 看到Api里已经有实例方法isInterrupted() 去判断了,为什么还要有一个类方法interrupted() 呢,而且做的事情还是完全一样的。

  • 那他到底是做什么的呢?

  • 在这个方法里面可以看自己是否被中断了 (调用Thread的实例方法)

  • 上图所示定义了一个t,里面复写了run()方法,这边是可以这样去用的,那如果线程不是这样定义的,而是这样定义的怎么办的呢?

  • 一样是复写run()方法,但是这里不能在使用isInterrupted()了,必须去调Thread.interrupted()

  • Thread.interrupted()拿到的也是当前线程t

isInterrupted()与interrupted()的源码

  • 如图所示两个调用的都是同一个东西

  • 这个就是有个实例方法和类方法要做的事情是一样的。

join()的打断方式

  • 这里调用join()方法后,就会抛出这个异常到这里吗?

  • 肯定是不会的因为应该还有其他线程去打断她。

  • 还要写一个线程,因为程序运行到这里会 block 住。

  • 线程t2休眠100毫秒,然后把t打断,主要是看下join那边会不会抛异常。

  • 这里的t是final修饰的,Java8中对这个语法团可以不进行显示的声明。

  • 运行结果:

  • 执行完后并没有被打断,之前的 t.interrupt();不管是sleep()还是wait()都会打断,但是这里是为什么呢?

  • 分析:

    • sleep时是当前线程t,然后做t的打断没问题。
    • wait时是当前线程t,然后做t的打断没问题。
    • join时是main线程,然后打断的是t线程。
  • 干掉main线程()

  • 运行结果:

  • 其实join()里面用的还是有用wait()方法做了一下。

  • 大家一定要会去分析,运行过程中不一定是那一个线程。

  • 这些小技巧在后面会非常有用,尤其是当用t.stop()停止不了线程时。

results matching ""

    No results matching ""