美文网首页工作生活
Java线程基础 : 线程的中断 & Interrupt

Java线程基础 : 线程的中断 & Interrupt

作者: 贪睡的企鹅 | 来源:发表于2019-07-04 23:50 被阅读0次

interrupt的理解

言归正传,要中断一个Java线程,可调用线程类(Thread)对象的实例方法:interrupte();然而interrupte()方法并不会立即执行中断操作;
具体而言,这个方法只会给线程设置一个为true的中断标志(中断标志只是一个布尔类型的变量),而设置之后,则根据线程当前的状态进行不
同的后续操作。

  • 1 线程的当前状态处于非阻塞状态,那么仅仅是线程的中断标志被修改为true而已。

  • 2 线程的当前状态处于阻塞状态,那么在将中断标志设置为true后,还会有如下三种情况之一的操作:

    • 如果是wait、sleep以及jion三个方法引起的阻塞,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException;
    • 如果是java.nio.channels.InterruptibleChannel进行的io操作引起的阻塞,则会对线程抛出一个ClosedByInterruptedException;(待验证)
    • 如果是轮询(java.nio.channels.Selectors)引起的线程阻塞,则立即返回,不会抛出异常。
  • 3 如果在中断时,线程正处于非阻塞状态,则将中断标志修改为true,而在此基础上,一旦进入阻塞状态,则按照阻塞状态的情况来进行处理;

常用API

interrupt()

中断当前线程,设置中断标志true

如果当前线程正处于wait、sleep以及join三个方法引起的阻塞,将当前线程从阻塞中唤醒,并抛出抛出个InterruptedException异常,同时会将线程的中断标志重新设置为false

isInterrupted()

返回当前线程的中断状态,不清除当前中断状态

interrupted()

返回当前线程的中断状态,且清除当前中断状态(如果线程已经为true重新设置为false)

案例

import org.junit.Test;

import java.util.concurrent.locks.LockSupport;

/**
 * 当线程处于wait、sleep以及jion三个方法引起的阻塞,调用interrupt会将,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException
 * 当线程处于运行状态下,用interrupt会将,那么会将线程的中断标志设置为true
 * 当线程处于interrupt中断LockSupport阻塞将抛出异常,中断不会重置依旧为true
 * 
 * 为统一我们可以捕获InterruptedException后执行interrupt,这样统一所有异常中线程的标志
 */
public class InterruptTest {


    /**
     * 当线程处于wait、sleep以及jion三个方法引起的阻塞,调用interrupt会将,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException
     * 当线程处于运行状态下,用interrupt会将,那么会将线程的中断标志设置为true
     *
     * 为统一我们可以捕获InterruptedException后执行interrupt,这样统一所有异常中线程的标志
     *
     */
    @Test
    public void test1() throws InterruptedException {
        /** 启动一个线程 **/
        TnterruptRunnable1 t1 = new TnterruptRunnable1();
        t1.start();

        TnterruptRunnable2 t2 = new TnterruptRunnable2();
        t2.start();

        TnterruptRunnable3 t3 = new TnterruptRunnable3();
        t3.start();

        Thread.sleep(1000);

        t1.interrupt();
        System.out.println("t1当前线程是否已经被中断:" + t1.isInterrupted());

        t2.interrupt();
        System.out.println("t2当前线程是否已经被中断:" + t2.isInterrupted());

        t3.interrupt();
        System.out.println("t3当前线程是否已经被中断:" + t3.isInterrupted());
    }

    /**
     * 当线程处于interrupt中断LockSupport阻塞将抛出异常,中断不会重置依旧为true
     */
    @Test
    public void test2() throws InterruptedException {
        TnterruptRunnable4 t1 = new TnterruptRunnable4("t1");
        t1.start();
        t1.interrupt();
        Thread.sleep(5000);

    }
}

class TnterruptRunnable1 extends Thread {


    public void run() {
        try {
            while (true) {
                Thread.sleep(1000l);
            }
        } catch (InterruptedException e) {
            return;
        }
    }
};

class TnterruptRunnable2 extends Thread {


    public void run() {
        while (true) {
            boolean isIn = this.isInterrupted();
            if (isInterrupted()) break;
        }
    }
};


class TnterruptRunnable3 extends Thread {


    public void run() {
        try {
            while (true) {
                Thread.sleep(1000l);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
};

class TnterruptRunnable4 extends Thread {
    public TnterruptRunnable4(String name) {
        super.setName(name);
    }

    public void run() {
        synchronized (InterruptTest.class) {
            System.out.println("in " + getName());
            LockSupport.park();
            if (Thread.currentThread().isInterrupted()) {
                System.out.println(getName() + " 被中断了!");
                System.out.println(Thread.currentThread().isInterrupted());
            }
        }
        System.out.println(getName() + " 执行结束");
    }
}

相关文章

网友评论

    本文标题:Java线程基础 : 线程的中断 & Interrupt

    本文链接:https://www.haomeiwen.com/subject/tpqjhctx.html