读《Java核心技术 卷一》记录。

当线程得 run 方法执行方法体中最后一条语句后,并经由执行 return 语句返回时,或者出现了在方法中没有捕获的异常时,线程将终止。在Java的早期版本中,还有一个 stop 方法,其他线程可以调用它终止线程。但是,这个方法现在已经被弃用了。(因为暴力停止)

没有可以强制线程终止的方法。然而,interrupt 方法可以用来请求终止线程。

当对一个线程调用 interrupt 方法时,线程的中断状态将被置位。这是每个线程都具有的 Boolean 标志。每个线程都应该不时地检查这个标志,以判断是否被中断。

要想弄清中断状态是否被置位,首先调用静态的 Thread.currentThread 方法获取当前线程,然后调用 isInterrupted 方法:

伪代码

while(!Thread.currentThread().isInterrupted() && more work do ){
	do more work
}

但是,如果线程被阻塞,就无法检测中断状态。这是产生 InterruptedException 异常的地方。当在一个被阻塞的线程(调用 sleep 或 wait)上调用 interrupt 方法时,阻塞调用将会被 Interrupt Exception 异常中断。

没有任何语言方面的需求要求一个被中断的线程应该终止。 中断一个线程不过是引起它的注意。被中断的线程可以决定如何响应中断。某些线程是如此重要以至于应该处理完异常后,继续执行,而不理会中断。但是,更普遍的情况是,线程将简单地将中断作为一个终止的请求。这种线程的 run 方法具体如下形式:

伪代码

Runnable r = () ->{
  try {
      while (!Thread.currentThread().isInterrupted() && do more work){
           do more work 
      }
  }catch (InterruptedException e){
      // thread was interrupted during sleep or wait
  }finally {
       cleanup ,if required
  }
    // exiting the run method terminates the thread
};

如果在每次工作迭代之后调用 sleep 方法(或者其他的可中断方法),isInterrupted 检测既没有必要也没有用处。如果在中断状态被置位时调用 sleep 方法,它就不会休眠。相反,它将清除这个状态(!)并抛出 InterruptedException。因此,如果你的循环调用 sleep,不会检测中断状态。相反,要如下所示捕获 InterruptedException 异常:

伪代码

Runnable r = () ->{
    try {
        while (!Thread.currentThread().isInterrupted() && do more work){
            do more work
            Thread.sleep(delay);
        }
    }catch (InterruptedException e){
        // thread was interrupted during sleep 
    }finally {
        cleanup ,if required
    }
    // exiting the run method terminates the thread
};

void interrupt()
向线程发送中断请求。线程的中断状态将被设置为 true。如果目前该线程被一个 sleep 调用阻塞,那么,InterruptedException 异常将被抛出。

static boolean interrupted()
测试当前线程(即正在执行这一命令的线程)是否被中断。注意,这是一个静态方法。这一调用会产生副作用——它将当前线程的中断状态重置为 false。

boolean isInterrupted()
测试线程是否被中断。不像静态的中断方法,这个调用不改变线程的中断状态。

static Thread currentThread()

返回代表当前执行线程的 Thread 对象。

interrupted 方法是一个静态方法,它检测当前的线程是否被中断。而且, interrupted 方法会清除该线程的中断状态。 isInterrupted 方法是一个实例方法,可用来检测是否有线程被中断。调用这个方法不会改变中断状态。

Java 线程提交线程池后强制停止_静态方法

从源码上很容易看出区别。