JUC编程之——线程中断机制及源码分析

1 什么是中断机制

  • 一个线程不应该由其他线程中断或停止,而应该由线程自行停止——命运掌握在自己手里;
  • 所以Thread.stop、Thread.suspend、Thread.resume方法都已过时;
  • Java中无法立即停止一个线程;
  • Java提供了一种用于停止线程的协商机制——中断,也即中断标识协商机制;
  • 中断过程需要程序员自己实现——用线程的interrupt方法将对象的中断标识设置为true——只是温馨提示,不是强制终止;


2 中断的相关API方法之三大方法说明

  • void interrupt():
    • 中断此线程;
    • 只是设置中断标志位,发起一个协商;
  • static boolean interrupted():
    • 测试当前线程是否已被中断;
    • 静态方法;
    • 方法做了两件事:
      • 返回当前线程的中断状态,测试当前的线程是否已被中断;
      • 将当前线程的中断状态清零并重新设为true,清除线程的中断状态;
  • boolean isInterrupted():
    • 判断当前线程是否被中断(通过检查中断标志位);
    • 和第一个方法配合使用;

3 如何停止中断运行中的线程——代码示例

3.1 通过关键字volatile变量实现

import java.util.concurrent.TimeUnit;


public class InterruptDemo
{
private static volatile boolean isStop = false;

public static void main(String[] args)
{
    new Thread(() -> {
        while(true)
        {
            // 需要退出了 or 需要中断了
            if(isStop)
            {
                System.out.println(Thread.currentThread().getName()+"线程------isStop = true,自己退出了");
                break;
            }
            System.out.println("-------hello interrupt");
        }
    },"t1").start();

    //暂停几秒钟线程
    try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
    isStop = true;
}

3.2 通过AtomicBoolean类实现

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

public class StopThreadDemo
{
    private final static AtomicBoolean atomicBoolean = new AtomicBoolean(true);

    public static void main(String[] args)
    {
        new Thread(() -> {
            while(true)){
                if(atomicBoolean.get()){
                    System.out.println(
                        Thread.currentThread().getName() + "\t atomicBoolean 被修改为true 线程停止"
                    );
                    break;
                }
            
                System.out.println("t1-----hello");
            }
        }, "t1").start();

        // 小睡一会
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }

        // 另一个线程
        new Thread(() -> {
            atomicBoolean.set(true);
        },"t2").start();
    }
}


}

3.3 通过Thread类自带的中断API方法实现

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

public class InterruptTest {

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while(true) {
                // 中断
                if(Thread.currentThread().isInterrupted()) {
                    System.out.println(Thread.currentThread().getName() + "\t 中断");
                    break;
                }

                System.out.println("----t1 interrupt");
            }
        },"t1");
        t1.start();

        try {
            TimeUnit.MILLISECONDS.sleep(20);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        new Thread(() -> {
            t1.interrupt();
        },"t2").start();
    }
}

4 中断方法底层源码分析

4.1 interrupt()方法——无返回值

  • interrupt方法作用:中断此线程;
  • 仅仅是将中断标识位从false设置为true
  • 并不是立刻停止线程
  • 如果线程处于被阻塞状态(例如处于sleep, wait, join 等状态),在别的线程中调用当前线程对象的interrupt方法,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。;
  • 中断不活动的线程不会产生任何影响;
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
            	// 实际调用interrupt0()
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }

调用底层native方法:

    private native void interrupt0();

4.2 isInterrupted()方法

public boolean isInterrupted() {
        return isInterrupted(false);
    }

底层还是调用native方法:

// Tests if some Thread has been interrupted. 
// The interrupted state is reset or not based on the value of ClearInterrupted that is passed.
    private native boolean isInterrupted(boolean ClearInterrupted);

你可能感兴趣的:(java,jvm,开发语言)