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();
        }
    }
}
相关推荐
utf8mb4安全女神18 小时前
⽇志管理与深层防⽕墙
java·开发语言·spring boot
better_liang18 小时前
每日Java面试场景题知识点之-数据库与缓存的一致性
java·数据库·redis·面试·分布式系统·缓存一致性·cache aside
减瓦18 小时前
Jackson 自定义反序列化器的类型不匹配陷阱
java·后端
qq_4523962318 小时前
第九篇:《Dockerfile 指令精讲(二):WORKDIR、ENV、ARG、EXPOSE》
java·开发语言·docker
JAVA社区18 小时前
Java高级全套教程(九)—— SpringCloud超详细实战详解
java·开发语言·后端·spring cloud·面试·职场和发展
wyjcxyyy18 小时前
java反序列化-cc1链
java·c语言·开发语言
garmin Chen18 小时前
Elasticsearch(1):Elasticsearch核心原理与基础操作总结
java·大数据·笔记·elasticsearch·搜索引擎·全文检索
Devin~Y18 小时前
大厂Java面试实录:Spring Boot/Cloud、Kafka、Redis、K8s 可观测性 + RAG/Agent(小Y翻车版)
java·spring boot·redis·spring cloud·kafka·kubernetes·mybatis
林森lsjs18 小时前
【日耕一题】2. 面向对象 Java 基础:构造方法与 toString
java·开发语言
学代码的真由酱18 小时前
【自用】测开面试问题-Java
java·面试·职场和发展