Nixo Home

如何停止一个线程?

字数统计: 769阅读时长: 2 min
2019/07/01 Share

如何停止一个线程

面试官想考察什么?

  • 是否对线程的用法有所了解(初级)
  • 是否对线程的stop()方法有所了解(初级)
  • 是否对线程的stop过程中存在的问题有所认识(中级)
  • 是否熟悉interrupt中断的用法(中级)
  • 是否能解释清除使用boolean标志位的好处(高级)
  • 是否知道interrupt底层的细节(高级)
  • 是否能通过该题目转移话题到线程安全,并阐述无误(高级)

剖析题目: 停止线程

停止线程有stop()方法,但是已经废弃(因为直接stop一个线程会有锁以及资源没有被释放的问题)

  • 以上所述,不能简单的停止一个线程(而应该将线程中任务全部执行完毕或者关闭,让线程任务终止而结束)
  • 如何设计可以随时被中断而取消的任务线程

线程是协作的任务执行模式

  • 通知目标线程自动结束,而不是强制停止
  • 目标线程应具备处理中断的能力
  • 中断方式
    • interrupt
    • boolean标志位

interrupt(原生支持)

  • sleep(){
    sleep方法会捕获InterruptEcaption,当我们调用thread.interrupt() 就可以在catch中处理任务,任务全部结束,线程就会关闭
    }

  • 如果线程里有很多次循环是不支持interrupt的{
    我们可以添加判断来支持interrupt
    例:

    ``java
        for(int i = 0 , i <10000,i++){
            if(interrupted()){
                true->中断
                break;
            }
            todo...
        }
    并且调用thread.interrupt() 这样for的时候就可以判断并且break.

``

}

interrupted() 于 isInterrupted()

  • interrupted()是静态方法,获取当前线程的中断状态,并清空。
    • 当前运行的线程
    • 中断状态调用后清空,重复调用后续返回false
  • isInterrupted()是非静态方法,获取该线程的中断状态,不清空
    • 调用线程对象对应的线程
    • 可重复调用,中断请空前一直返回true.

-区别{
在JNI源码中 interrupted()调用的是底层线程的对象self的interrupted()
isInterrupted()JNI会找到JavaThread底层对应的C++线程实例随后调用它的isInterrupted()方法
底层interrupted()于isInterrupted()方法不同的在于前者在多调用了清空当前中断状态的方法,并且方法里面加了wait_mutex锁,后者则没有。
}

volatile Boolean标志位

  • 在线程中添加volatile boolean 对象标志位(其实就是对象)

  • 在线程外更改这个boolean的值,在线程中不断地if这个标志位即可

  • 为什么要使用volatile?{
    volatile 保持该标志位的可见性,因为调用者于对象存在的不在一个线程中,在java的内存模型上,可能会导致不可见
    而且相对于其他线程来说,该标志位是可见的,所以需要加volatile锁保持标志位的原子性与可见性(因为执行时不一定是正常顺序)
    }

interrupted与Boolean对比

  • 需要支持系统方法时用中断用interrupted()(功能性)
  • 其他情况用Boolean标志位(性能)
CATALOG
  1. 1. 如何停止一个线程
  2. 2. 面试官想考察什么?
  3. 3. 剖析题目: 停止线程
  4. 4. 线程是协作的任务执行模式
  5. 5. interrupt(原生支持)
  6. 6. interrupted() 于 isInterrupted()
  7. 7. volatile Boolean标志位
  8. 8. interrupted与Boolean对比