20240427-线程基础-结束线程

线程基础-结束线程

1.stop()方法

2.使用共享变量

java 复制代码
package com.ysf.day0427;

public class Tst03ShareVar {

    static volatile boolean flag = true;

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (flag){
                //处理业务
            }
            System.out.println("任务结束");
        },"share-1");
        t.start();
        Thread.sleep(1000L);
        flag = false;
    }
}

3.使用interrupt

3.1 interrupt标记位

  • 线程中存在一个标记位interrupt,来标识线程是否被打断
  • 该标记位默认情况下是false

3.2 查询线程标记位

  • 对象方法:isInterrupted()
java 复制代码
package com.ysf.day0427;

public class Tst04QueryInterrupt {

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(()->{
            for (int i = 0;i<5;i++){
                System.out.println(i);
                try {
                    Thread.sleep(500L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"interrupt-1");
        t1.start();
        Thread.sleep(1000L);
        System.out.println(t1.isInterrupted());
    }
}

3.3设置线程interrupt标记位为true

  • 对象方法:interrupt()
  • 作用:
    • 改变标记位为true
    • 打断线程的WAITING或者TIMED_WAITING状态
  • 用法:
    • 当用作设置线程结束的方法时(没有sleep,没有wait),标记位会有明显改变
    • 当作为打断线程WAITING或者TIMED_WAITING状态的方法时,线程的标记位是不会被改变的
java 复制代码
package com.ysf.day0427;

import java.util.Date;

public class Tst05SetInterrupt {

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(()->{
            int count = 0;
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("业务处理" + count);
                count++;
                // 这里用于证明,在调用了interrupt()方法后,并没有改变线程的标记位
                System.out.println(Thread.currentThread().isInterrupted());
                try {
                    System.out.println("开始睡眠");
                    // 睡眠50秒,方便被main线程打断,可以清晰的看出线程并没有睡足50秒
                    Thread.sleep(50000L);
                } catch (InterruptedException e) {
                    // 当捕获到这个异常的时候会有两种情况
                    // 情况1:我只想打断沉睡
                    // 情况2:我想退出线程
                    if (count<20){
                        // 模拟情况1,如果count小于20的话,那我只想打断沉睡
                        continue;
                    }else {
                        // 模拟情况2,如果count不小于20的话,那我想退出线程
                        // 这里我们不用break或return,我们使用改变标记位的方式
                        // 为什么这里还要再打断一次,因为main线程的打断只是改变了线程WAITING状态,并没有改变标记位
                        Thread.currentThread().interrupt();
                    }
                }
            }
            System.out.println("线程结束");
        },"interrupt-1");
        t1.start();
        // 睡一秒,等待t线程启动
        Thread.sleep(1000L);
        for (int i = 0;i<21;i++){
            Thread.sleep(1000L);
            t1.interrupt();
        }
    }
}

3.3查询线程标记位,并将标记位设置为false

  • 静态方法:Thread.interrupted()
  • 作用:
    查询线程的标记位,并且将标记位设置为false
java 复制代码
package com.ysf.day0427;

public class Tst06SetInterruptFalse {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(()->{
            int count = 0;
            String name = Thread.currentThread().getName();
            while (!Thread.currentThread().isInterrupted()){
                System.out.println(name + "==>" + count);
                count++;
                // 这里用于证明,在调用了interrupt()方法后,并没有改变线程的标记位
                System.out.println(Thread.currentThread().isInterrupted());
                try {
                    System.out.println(name + "==>" + "开始睡眠");
                    // 睡眠50秒,方便被main线程打断
                    Thread.sleep(50000L);
                } catch (InterruptedException e) {
                    // 当捕获到这个异常的时候会有两种情况
                    // 情况1:我只想打断沉睡
                    // 情况2:我想退出线程
                    if (count<3){
                        // 模拟情况1,如果count小于3的话,那我只想打断沉睡
                        continue;
                    }else {
                        // 模拟情况2,如果count不小于3的话,那我想退出线程
                        // 这里我们不用break或return,我们使用改变标记位的方式
                        // 为什么这里还要再打断一次,因为main线程的打断只是改变了线程WAITING状态,并没有改变标记位
                        System.out.println(name + "==>" + "count不小于3了");
                        Thread.currentThread().interrupt();
                        // 那如果我在调用了打断之后,我又有其他情况不想退出了呢?
                        // 我们可以在此基础上再调用一次静态方法
                        System.out.println(name + "==>" + Thread.interrupted());
                    }
                }
            }
            System.out.println(name + "==>" + "线程结束");
        },"interrupt-1");
        t1.start();
        // 睡一秒,等待t线程启动
        Thread.sleep(1000L);
        for (int i = 0;i<3;i++){
            String name = Thread.currentThread().getName();
            Thread.sleep(1000L);
            System.out.println(name + "==>" + "开始执行第" + i + "次打断");
            t1.interrupt();
        }
    }
}
相关推荐
xieliyu.10 分钟前
Java 文件IO :File 文件类、字节流、字符流讲解
java·ide·笔记·javaee
云烟成雨TD21 分钟前
Micrometer 系列【28】Spring Boot Actuator | 其他指标速览
java·spring boot·云原生
meilindehuzi_a23 分钟前
深入理解 Linux 进程地址空间:从虚拟内存、页表映射到 fork 写时拷贝与 VMA 管理
java·linux·服务器
莫得感情 o30 分钟前
设计模式 13 · 桥接模式
java·设计模式·桥接模式
吠品30 分钟前
Java中实现拓扑排序的两种方式:Kahn算法和DFS
java·数据库·notepad++
TunerT_TQ41 分钟前
企业智能体工程体系v1.1|企业智能体工程卷 · 第5期· 数据飞轮——用观察—分析—计划—执行持续改进
java·运维·网络·#agent工程化·#企业智能体·#多智能体系统·#数据飞轮
小当家.1051 小时前
工具并行调用原理与实现:CompletableFuture 实战
java·agent·线程池·工具·并行
wangjialelele1 小时前
Spring Cloud 全体系学习笔记(REST、Nacos、Feign、Gateway)
java·spring boot·笔记·学习·spring·spring cloud·gateway
yk 坤帝1 小时前
用Python算清你的“买时间“账
java·服务器·python
weixin_BYSJ19871 小时前
springboot医疗信息管理系统---附源码17465
java·javascript·spring boot·python·django·flask·php