0
点赞
收藏
分享

微信扫一扫

Java线程中断机制

kmoon_b426 2023-11-28 阅读 32

1、一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。因此,Java提供了一种用于停止线程的协商机制--中断,也即中断标识协商机制。

中断只是一种协作协商机制,Java没有给中断增加任何语法,中断的过程完全需要程序员自己实现。它与stop最大的区别是:stop是由系统强制终止线程,而线程中断则给目标线程发送一个中断信号,如果目标线程没有接受线程中断的信号并结束线程,线程则不会终止,具体是否退出或者执行其他逻辑由目标线程决定。

2、中断的相关方法

1)public void interrupt(): 仅仅是设置线程的中断状态为true,发起一个协商而不会立刻停止线程。

2)public static boolean interrupted():判断线程是否被中断,并清除当前中断状态这个方法做了两件事:

a.返回当前线程的中断状态。

b.将当前线程的中断状态设为false。

3)public boolean isInterrupted():通过检查中断标志位,判断当前线程是否被中断。

3、使用中断标识停止线程

中断机制就是子啊需要中断的线程中不断监听中断状态,一旦发生中断,就执行相应的中断处理业务逻辑stop线程。

3.1通过volatile变量实现

volatile保证了可见性,t2线程修改了标志位后能马上被t1线程看到

import java.util.concurrent.TimeUnit;

public class InterruptDemo1 {

    /**
     * 设置中断标识
     */
    private static volatile boolean isStop = false;

    public static void main(String[] args) throws InterruptedException{
        new Thread(new Runnable() {
            @Override
            public void run() {
                //通过while循环不断监听中断状态
                while (true){
                    //如果这个标志位被其他线程改为true
                    if (isStop){
                        System.out.println(Thread.currentThread().getName() + "\t isStop被修改为true");
                        break;
                    }
                    //如果没有停止,那就一直打印
                    System.out.println("t1 ----------------Hello volatile");
                }
            }
        },"t1").start();

        TimeUnit.MICROSECONDS.sleep(20);

        new Thread(()->{
           isStop = true;
        },"t2").start();
    }
}

3.2通过AtomicBoolean实现

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

public class InterruptDemo2 {

    //设置中断标志
    private static AtomicBoolean atomicBoolean = new AtomicBoolean(false);

    public static void main(String[] args) throws InterruptedException {

        new Thread(()->{
            //通过while循环不断监听中断状态
            while (true){
                //如果这个标志位被其他线程改为true
                if (atomicBoolean.get()){
                    System.out.println(Thread.currentThread().getName() + "\t isStop被修改为true");
                    break;
                }
                //如果没停止,那就一直打印
                System.out.println("t1-----Hello AtomicBoolean");
            }
        },"t1").start();

        TimeUnit.MICROSECONDS.sleep(20);
        
        new Thread(()->{
            atomicBoolean.set(true);
        },"t2").start();
    }
}

3.3 通过Thread类自带的中断api实现

默认的中断标志位是false,然后通过Thread类自带的interrupted方法被改为true。

import java.util.concurrent.TimeUnit;

public class InterruptDemo3 {

    public static void main(String[] args)  throws InterruptedException{

        Thread t1 = new Thread(()->{
            while (true){
                //通过while循环不断监听中断状态
                if (Thread.currentThread().isInterrupted()){
                    System.out.println(Thread.currentThread().getName()+"\t isInterrupted()被修改为true,程序终止");
                    break;
                }
                //如果没有停止,那就一直打印
                System.out.println("t1---Hello interrupt");
            }

        },"t1");
        t1.start();

        TimeUnit.MICROSECONDS.sleep(20);
        new Thread(()->{
            //把t1中断
            t1.interrupt();
        },"t2").start();

    }
}

4、API源码分析

实例方法interrupt(),没有返回值:仅仅是设置一个中断标志位。

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();
    }

调用底层的C语言

  private native void interrupt0();

实例方法isInterrupted,返回布尔值。

public boolean isInterrupted(){
  return interrupted;
}

private volatile boolean interrupted; //也调用了C语言

5、总结

当对一个线程调用interrupt()时:

a.如果线程处于正常活动状态,那么会将该线程的中断状态标志设置为true,仅此而已,被设置中断状态的线程将继续正常运行,不受影响。所以,interrupt()并不能真正的中断状态,需要被调用的线程自己进行配合才行。

b.如果线程处于被阻塞状态(例如处于sleep、wait、join等状态),在别的线程中调用当前线程对象的interrupt方法,那么线程将立即退出被阻塞状态,并抛出一个interruptedException异常。


举报

相关推荐

0 条评论