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();
        }
    }
}
相关推荐
yaoxin52112340 分钟前
384. Java IO API - Java 文件复制工具:Copy 示例完整解析
java·开发语言·python
NotFound4861 小时前
实战指南如何实现Java Web 拦截机制:Filter 与 Interceptor 深度分享
java·开发语言·前端
一 乐3 小时前
医院挂号|基于springboot + vue医院挂号管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·医院挂号管理系统
鱼鳞_3 小时前
Java学习笔记_Day29(异常)
java·笔记·学习
烟锁池塘柳03 小时前
一文讲透 C++ / Java 中方法重载(Overload)与方法重写(Override)在调用时机等方面的区别
java·c++·面向对象
一叶飘零_sweeeet3 小时前
深入拆解 Fork/Join 框架:核心原理、分治模型与参数调优实战
java·并发编程
云烟成雨TD3 小时前
Spring AI Alibaba 1.x 系列【23】短期记忆
java·人工智能·spring
摇滚侠3 小时前
帮我整理一份 IDEA 开发中常用快捷键
java·ide·intellij-idea
疯狂成瘾者4 小时前
YAML配置介绍
java
cccccc语言我来了4 小时前
C++轻量级消息队列服务器
java·服务器·c++