Java多线程/并发08、中断线程 interrupt()

来源:互联网 发布:原始原素 知乎 编辑:程序博客网 时间:2024/05/21 04:43

一个线程是否能让另一个线程停止运行?除了线程同步互斥机制之外,还有两种方法:

  1. 可以使用Thread.stop(), Thread.suspend(), Thread.resume()
    和Runtime.runFinalizersOnExit() 这些终止线程运行的方法 。但这些方法已经被废弃(The method stop() from the type Thread is deprecated),使用它们是极端不安全的。
  2. Thread.interrupt() 方法是很好的选择。
public class InterruptDemo {    public static void main(String[] args) throws InterruptedException {        Runnable r = new TestRunnable();        Thread th1 = new Thread(r);        th1.start();        /*三秒后中断线程th1*/        Thread.sleep(3000);        th1.interrupt();    }}class TestRunnable implements Runnable {    public void run() {        while (true) {            System.out.println("Thread is running...");            long time = System.currentTimeMillis();// 获取系统时间的毫秒数            while((System.currentTimeMillis() - time < 1000)){                /*程序循环运行1秒钟,不同于sleep(1000)会阻塞进程。*/            }        }    }}

运行发现,线程th1并没有预期中断。
为什么呢?
每一个线程都有一个属性:中断状态(interrupted status) ,可以通过Thread.currentThread().isInterrupted() 来检查这个布尔型的中断状态。
当调用th1.interrupt()时,只是改变了线程th1的中断状态。要想真正让线程th1中断,只能是th1自己来实现任务控制。
在上面的程序中,把TestRunnable类中的while (true)修改为while (!Thread.currentThread().isInterrupted()),程序即可达到我们期望

interrupt无法修改正在阻塞状态(如被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞时)的线程。如果尝试修改,会触发异常:java.lang.InterruptedException
上面的程序把TestRunnable修改成:

class TestRunnable implements Runnable {    public void run() {        while (!Thread.currentThread().isInterrupted()) {            System.out.println("Thread is running...");            long time = System.currentTimeMillis();// 获取系统时间的毫秒数            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                System.out.print(e.getMessage());            }        }    }}

运行几秒便会报错,因为当线程在Thread.sleep时,外部线程尝试调用interrupt()修改它的中断状态(interrupted status) 。

Core Java中有这样一句话:”没有任何语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断 “。
换言之,没有任何人可以逼迫美女嫁给自己,告诉她“我要娶你”是你的事,至于嫁不嫁最终由她决定。

0 0
原创粉丝点击