zoukankan      html  css  js  c++  java
  • 线程协作-中断

    一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果. 所以你看到线程的suspend()、resume()和stop()方法(线程的暂停、恢复和终
    止)被废弃

    应用场景:
        (1)不能直接把一个线程搞挂掉, 但有时候又有必要让一个线程死掉, 或者让它结束某种等待的状态该怎么办呢? 优雅的方法就是, 给那个线程一个中断信号, 让它自己决定该怎么办。

         (2)在某个子线程中为了等待一些特定条件的到来, 你调用了Thread.sleep(10000), 预期线程睡10秒之后自己醒来, 但是如果这个特定条件提前到来的话, 你怎么通知一个在睡觉的线程呢?(主线程中断子线程)

         (3) 主线程通过调用子线程的join方法阻塞自己以等待子线程结束, 但是子线程运行过程中发现自己没办法在短时间内结束, 于是它需要想办法告诉主线程别等我了。(子线程中断主线程)

    中断实现:
           中断是通过调用Thread.interrupt()方法来做的。这个方法通过修改了被调用线程的中断状态来告知那个线程, 说它被中断了。

           对于非阻塞中的线程, 只是改变了中断状态, 即Thread.isInterrupted()将返回true; 对于可取消的阻塞状态中的线程, 比如等待在这些函数上的线程, Thread.sleep(), Object.wait(), Thread.join(), 这个线程收到中断信号后, 会抛出InterruptedException, 同时会把中断状态置回为false。

    程序演示:

    下面的程序会演示对非阻塞中的线程中断:

    public class Main {

    public static class Thread3 extends Thread{
    public void run(){
    while(true){
    if(Thread.interrupted()){//返回true, 但是中断状态置回为false
    System.out.println("Someone interrupted me.");
    } else{
    System.out.println("Going...");
    }
    long now = System.currentTimeMillis();
    while(System.currentTimeMillis()-now<1000){
    // 为了避免Thread.sleep()而需要捕获InterruptedException而带来的理解上的困惑,
    // 此处用这种方法空转1秒
    }
    }
    }
    }

    public static void main(String[] args) throws InterruptedException {
    Thread3 t = new Thread3();
    t.start();
    Thread.sleep(3000);
    t.interrupt();
    System.out.println("hahah");
    }
    }

    下面的程序演示的是子线程通知父线程(阻塞中)别等它了:

    
    
    public class Main {

    public static class Thread4 extends Thread {
    private Thread parent;

    public Thread4(Thread parent) {
    this.parent = parent;
    }

    public void run() {
    while (true) {
    System.out.println("sub thread is running...");
    long now = System.currentTimeMillis();
    while (System.currentTimeMillis() - now < 2000) {
    // 为了避免Thread.sleep()而需要捕获InterruptedException而带来的理解上的困惑,
    // 此处用这种方法空转2秒
    }
    parent.interrupt();
    }
    }
    }

    public static void main(String[] args){
    Thread4 t = new Thread4(Thread.currentThread());
    t.start();
    try {
    Thread.sleep(10000);
    t.wait();
    t.join();
    } catch (InterruptedException e) {
    System.out.println(Thread.interrupted());
    System.out.println(Thread.currentThread().isInterrupted());
    System.out.println("Parent thread will die...");
    }
    }
    }

    注意:

    1. 中断状态可以通过 Thread.isInterrupted()来读取,并且可以通过一个名为 Thread.interrupted()的静态方法读取和清除状态(即调用该方法结束之后, 中断状态会变成false)。

     

    2. 不是所有的阻塞方法收到中断后都可以取消阻塞状态:  输入和输出流类会阻塞等待 I/O 完成,收到中断后,它们不抛出 InterruptedException,而且在被中断的情况下也不会退出阻塞状态。

    3.尝试获取一个内部锁的操作(进入一个 synchronized 块)是不能被中断的,但是 ReentrantLock 支持可中断的获取模式即 tryLock(long time, TimeUnit unit)。

  • 相关阅读:
    PAT Advanced 1067 Sort with Swap(0, i) (25分)
    PAT Advanced 1048 Find Coins (25分)
    PAT Advanced 1060 Are They Equal (25分)
    PAT Advanced 1088 Rational Arithmetic (20分)
    PAT Advanced 1032 Sharing (25分)
    Linux的at命令
    Sublime Text3使用指南
    IntelliJ IDEA创建第一个Groovy工程
    Sublime Text3 安装ftp插件
    Sublime Text3配置Groovy运行环境
  • 原文地址:https://www.cnblogs.com/DengGao/p/java-interrupted.html
Copyright © 2011-2022 走看看