你知道被中断的线程,运行状态发生了什么变化吗?

    xiaoxiao2023-11-03  154

    今天我们来一起聊一个问题: “被中断的线程,运行状态发生了什么变化” Java中的中断并不是说会把正在运行的线程终止,而是仅仅设置下线程的中断标志,列如下面的代码:

    package JavaDemo; /** * @program: JavaDemo * @description: * @author: 码上Java * @create: 2019-05-25 16:39 */ public class Main { private static final String THREAD_NUM="biz-thread"; public static void main(String[] args) throws InterruptedException { //创建线程,内部任务是死循环 Thread thread=new Thread(new Runnable() { @Override public void run() { for (;;){ System.out.println("I am a sub thread"); try { Thread.sleep(1000); } catch (InterruptedException e) { //不捕获该异常 } } } },THREAD_NUM); //启动 thread.start(); //用户线程休眠3s Thread.sleep(3000); //中断子线程 System.out.println("--begin interrupt sub thread--"); thread.interrupt(); System.out.println("--end interrupt sub thread--"); } }

    如上代码运行情况如下图所示: 如上代码创建了一个子线程启动,子线程间隔1s打印输出,main函数所在线程休眠3s后,调用子线程的interrupt方法中断子线程,可知子线程被中断后继续间隔1s打印一句,这说明设置线程中断标志并不会改变线程的运行状态,更不会打断线程的执行。 Thread类中关于中断的方法有三个:

    void interrupt()方法:中断线程,仅仅设置线程的中断标志位true并立即返回,线程的运行状态并不会发生变化。 源码如下:

    public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { interrupt0(); // Just to set the interrupt flag b.interrupt(this); return; } } interrupt0(); }

    boolean isInterrupted() :检测当前线程是否被中断,如果是返回true,否则返回false。 源码如下:

    public boolean isInterrupted() { //传递false,说明不清除中断标志 return isInterrupted(false); }

    boolean interrupted() :检测当前线程是否被中断,如果是返回true,否则返回false。与isInterrupted不同的是,该方法发现当前线程被中断后会清除中断标志。 源码如下:

    private native boolean isInterrupted(boolean ClearInterrupted);

    需要注意的是,当一个线程处于休眠的时候,如果其他线程中断了它,则处于休眠的线程会抛出java.lang.InterruptedException异常而返回:

    public class Main { private static final String THREAD_NUM="biz-thread"; public static void main(String[] args) throws InterruptedException { //创建线程 Thread thread=new Thread(new Runnable() { @Override public void run() { System.out.println("I am a sub thread"); try { Thread.sleep(10000000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("--I am interrupted--"); } },THREAD_NUM); //启动 thread.start(); //用户线程休眠3s Thread.sleep(3000); //中断子线程 System.out.println("--begin interrupt sub thread--"); thread.interrupt(); System.out.println("--end interrupt sub thread--"); } }

    如上代码运行情况如下图所示: 以上代码中,子线程调用了Thread.shleep(10000000);,表示自己休眠10000s,在没其他线程干扰的情况下,子线程需要等10000s后才会从sleep返回,但是这里main函数所在线程休眠3s后中断了子线程,这时候子线程从sleep处抛出java.lang.InterruptedException异常后返回了。

    Java中的线程中断只是简单设置中断标志,至于剩下的事情就需要我们自己来做,比如根据中断标志来判断是否退出执行。

    下面看一下线程使用Interrupted优雅退出的经典例子,代码如下:

    //创建线程 Thread thread=new Thread(new Runnable() { @Override public void run() { //如果当前线程被中断则退出循环 while (!Thread.currentThread().isInterrupted()) System.out.println(Thread.currentThread()+"Hello"); } });
    最新回复(0)