Java并发编程高级 难点 多线程中断机制 中断机制 volatile变量 原子类 Thread自带API interrupt()和isInterrupt()

目录

面试题

什么是中断 理论

不允许停别人的线程

中断 API 的相关方法

如何使用中断标志位中断线程

通过一个 volatile 变量实现

通过原子操作类实现

用 Thread 自带的中断 API 方法

源码解析 interrupt()

源码解析 isInterrupt()

样例 1 简单 正常打断

样例 2 困难 不会立刻打断

样例 3 困难 强制打断 重要

静态方法 interrupt()

结论

代码

输出

底层源码


最难的

面试题

什么是中断 理论

首先

一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。

所以,Thread.stop,Thread.suspend, Thread.resume 都已经被废弃了。

其次

在Java中没有办法立即停止一条线程,然而停止线程却显得尤为重要,如取消一个耗时操作。

因此,Java提供了一种用于停止线程的机制--中断。

中断只是一种协作机制,Java没有给中断增加任何语法,中断的过程完全需要程序员自己实现。

若要中断一个线程,你需要手动调用该线程的interrupt方法,该方法也仅仅是将线程对象的中断标识设成true;

接着你需要自己写代码不断地检测当前线程的标识位,如果为true,表示别的线程要求这条线程中断,

此时究竟该做什么需要你自己写代码实现。

每个线程对象中都有一个标识,用于表示线程是否被中断;该标识位为true表示中断,为false表示未中断:

通过调用线程对象的interrupt方法将该线程的标识位设为true;可以在别的线程中调用,也可以在自己的线程中调用。

多线程中

每一条线程的命运掌握在自己手中

中断

中断协商机制

调用方法 interrupt 发起中断协商机制

注意只是协商

并不是 立即 + 马上 + now, stop 一个线程

不允许停别人的线程

但不是立刻停止这个线程

只是发起中断协商机制

接着你需要写代码不断记得检测当前线程的标识位

如果为 true

标识别的线程要求这条线程中断


每个线程对象中都有一个表示用于表示当前线程是否被中断

标识位为 true 为中断 false 未中断

通过调用线程对象的 interrupt 方法将该线程的表示为设为 true 可以在别的线程里面调用 也可以在自己的线程里面调用

中断 API 的相关方法

如何使用中断标志位中断线程

在需要中断的线程中不断监听中断状态

一旦发生中断

就执行相应的中断处理业务逻辑

通过一个 volatile 变量实现

volatile变量具有可见性

在一个线程里面修改 volatile 变量

另一个线程是完全可见的

import java.util.concurrent.TimeUnit;

public class InterruptDemo {
    // 如何在多线程环境下优雅的退出某个线程
    static volatile boolean isStop = false;
    public static void main(String[] args) {
        // 通过一个volatile变量实现
        new Thread(() ->{
            while (true){
                if(isStop){
                    System.out.println("程序结束");
                    break;
                }
                System.out.println("hello isStop");
            }
        },"t1").start();

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

        // volatile变量具有可见性
        new Thread(() ->{
            isStop = true;
        },"t2").start();

    }
}

通过原子操作类实现

原子操作类

AtomicBoolean

    public static void main(String[] args) {
        new Thread(() ->{
            while (true){
                if(atomicBoolean.get()){
                    System.out.println("程序结束");
                    break;
                }
                System.out.println("hello isStop");
            }
        },"t1").start();

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

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

用 Thread 自带的中断 API 方法

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

public class InterruptDemo {
    // 如何在多线程环境下优雅的退出某个线程

    // volatile修饰的变量
    static volatile boolean isStop = false;

    // 原子操作类 AtomicBoolean
    static AtomicBoolean atomicBoolean = new AtomicBoolean(false);

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("程序结束");
                    break;
                }
                System.out.println("hello isStop");
            }
        }, "t1");
        t1.start();

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

        new Thread(() ->{
            // 修改t1线程的中断标志位为true
            t1.interrupt();
        },"t2").start();
    }

    public static void m1(String[] args) {
        // 通过一个volatile变量实现
        new Thread(() ->{
            while (true){
                if(isStop){
                    System.out.println("程序结束");
                    break;
                }
                System.out.println("hello isStop");
            }
        },"t1").start();

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

        // volatile变量具有可见性
        new Thread(() ->{
            isStop = true;
        },"t2").start();
    }

    public static void m2(String[] args) {
        // 通过原子操作类实现
        new Thread(() ->{
            while (true){
                if(atomicBoolean.get()){
                    System.out.println("程序结束");
                    break;
                }
                System.out.println("hello isStop");
            }
        },"t1").start();

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

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

}

源码解析 interrupt()

源码解析 isInterrupt()

样例 1 简单 正常打断

import java.util.concurrent.TimeUnit;

public class InterruptHardDemo {

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("t1 线程别打断了程序结束");
                    break;
                }
//                System.out.println("hello isStop");
            }
        }, "t1");
        t1.start();

        System.out.println(t1.isInterrupted());

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

//        new Thread(() ->{
//            // 修改t1线程的中断标志位为true
//            t1.interrupt();
//        },"t2").start();

        t1.interrupt();

        System.out.println(t1.isInterrupted());

    }

}

中断不是立即 stop

样例 2 困难 不会立刻打断

输出

非活动线程的中断标志为 false

样例 3 困难 强制打断 重要

3 秒后正常打断

输出

强制打断

这种是停止不了的

很容易造成生产事故

跟底层原理有关

在异常里面处理

输出

其实就是线程中断标志位复位为 false

无法停下

需要再次调方法

将中断标志位设置为 true

静态方法 interrupt()

结论

代码

输出

因为存在一个状态清空的逻辑

底层源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值