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();
        }
    }
}
相关推荐
suweijie7682 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
公贵买其鹿3 小时前
List深拷贝后,数据还是被串改
java
xlsw_6 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹7 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭8 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫8 小时前
泛型(2)
java
超爱吃士力架8 小时前
邀请逻辑
java·linux·后端
南宫生8 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石8 小时前
12/21java基础
java
李小白668 小时前
Spring MVC(上)
java·spring·mvc