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();
        }
    }
}
相关推荐
Pniubi3 小时前
模拟一个充值送token怎么保证幂等?一致性?原子性?
java
企业数字化笔记4 小时前
多租户配额怎么控制?用量口径、并发预留与超额处理的实现方法
java·数据库·spring boot
巴勒个啦4 小时前
Prompt Engineering 实战:5 个让 AI 生成生产级业务代码的工程模式
java·前端
倚楼听风语4 小时前
Kotlin 协程与 suspend 原理详解
java·算法·kotlin
开开心心就好5 小时前
文件被占用删不掉?解锁工具强制删除
java·运维·服务器·开发语言·前端·pdf·ocr
weixin_460443565 小时前
Java+Linux私有化训考平台:服务、数据库与终端部署结构解析
java·linux·数据库·私有化部署·企业培训考试系统·企业考试系统
云和数据.ChenGuang5 小时前
python大小整数范围解析
java·开发语言·python
Java内核笔记5 小时前
Spring AI 生产级 Chat 接口:6 个开关、13 个坑,其中 2 个开关根本没生效
java·人工智能·后端
雷一言说5 小时前
Spring AI 2.0 RAG:用 Metadata Filter 做多租户检索隔离
java·spring
WeiXin_DZbishe5 小时前
基于springboot装修风格选择系统的设计与开发-计算机毕设【课程设计】77964
java·vue.js·spring boot·后端·python·php·课程设计