多线程-sleep-yield-join

微服务存活状态监控线程,其实一般会每次检查完一轮之后,就要停顿几秒钟,此时可以用Thread.sleep()这个方法,指定要等待多少毫秒。但是其实这个东西平时你要指定等待多少毫秒,还挺麻烦的

JDK 1.5之后就引入了TimeUnit这个类,很方便

TimeUnit.HOURS.sleep(1)

TimeUnit.MINUTES.sleep(5)

TimeUnit.SECONDS.sleep(30)

TimeUnit.MILLISECONDS.sleep(500)

如果用TimeUnit的话,你在外面怎么配?你要是配置休眠5分钟,还得加一个单位,代码里要判断一下你休眠的时间单位,如果是分钟,那么还得用TimeUnit.MINIUTE来进行休眠,不太方便

但是我要跟大家说一点,开源项目的话,在线程sleep这块,还是用的最最原始的sleep,因为可以通过毫秒数,动态的传入一个外面配置的一个值

500

30 * 1000

1 * 60 * 1000

30 * 60 * 1000


担心说某个线程一直长时间霸占着CPU,导致其他的线程很少得到机会来执行,所以设计了一个yield方法,你调用之后,可以尝试说当前线程先别执行了,CPU,兄弟,你可以去执行其他线程了

如果你要用这个方法的话,必须在严格的测试环境下,做大量的测试,验证说,你在你需要的场景下,使用了yield方法,真的可以达到你需要的效果。很多人很少可以正确的使用这个yeild方法,这个方法常见于debug和test场景下的程序

在这样的一些场景下,他可以复现因为锁争用导致的一些bug

他也可以用于设计一些并发控制的工具,比如说在java.util.concurrent.locks包下的一些类

yield关键字 复制代码
public static void main(String[] args) {
    // 创建两个线程并启动
    Thread producer = new Thread(new Task("Producer"), "Producer");
    Thread consumer = new Thread(new Task("Consumer"), "Consumer");
    producer.start();
    consumer.start();
}

static class Task implements Runnable {
    private final String name;

    public Task(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println(name + " 执行步骤 " + i);

            // 在关键节点让出CPU资源
            if (i == 2) {
                System.out.println("【" + name + "】让出CPU控制权");
                Thread.yield(); // 提示调度器切换线程[1,3,6](@ref)
            }

            try {
                Thread.sleep(50); // 模拟短时操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(name + " 任务完成!");
    }
}
csharp 复制代码
public class ThreadJoinDemo {
    public static void main(String[] args) throws InterruptedException {
        // 创建两个任务线程
        Thread dataLoader = new Thread(new DataLoaderTask(), "DataLoader");
        Thread dataProcessor = new Thread(new DataProcessorTask(), "DataProcessor");

        System.out.println("【主线程】启动数据加载线程");
        dataLoader.start(); // 启动数据加载线程

        // 主线程等待dataLoader执行完毕
        dataLoader.join();
        System.out.println("【主线程】数据加载完成,启动数据处理线程");

        dataProcessor.start(); // 启动数据处理线程
        dataProcessor.join(); // 等待数据处理完成
        System.out.println("【主线程】所有任务完成!");
    }

    // 模拟数据加载任务
    static class DataLoaderTask implements Runnable {
        @Override
        public void run() {
            try {
                System.out.println("【" + Thread.currentThread().getName() + "】开始加载数据...");
                Thread.sleep(2000); // 模拟耗时操作
                System.out.println("【" + Thread.currentThread().getName() + "】数据加载完毕!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // 模拟依赖前置数据的处理任务
    static class DataProcessorTask implements Runnable {
        @Override
        public void run() {
            try {
                System.out.println("【" + Thread.currentThread().getName() + "】开始处理数据...");
                Thread.sleep(1500); // 模拟计算过程
                System.out.println("【" + Thread.currentThread().getName() + "】数据处理完成!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

相关推荐
神奇的程序员15 小时前
从已损坏的备份中拯救数据
运维·后端·前端工程化
oden16 小时前
AI服务商切换太麻烦?一个AI Gateway搞定监控、缓存和故障转移(成本降40%)
后端·openai·api
李慕婉学姐17 小时前
【开题答辩过程】以《基于Android的出租车运行监测系统设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·后端·vue
m0_7400437317 小时前
SpringBoot05-配置文件-热加载/日志框架slf4j/接口文档工具Swagger/Knife4j
java·spring boot·后端·log4j
招风的黑耳18 小时前
我用SpringBoot撸了一个智慧水务监控平台
java·spring boot·后端
Miss_Chenzr18 小时前
Springboot优卖电商系统s7zmj(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
期待のcode18 小时前
Springboot核心构建插件
java·spring boot·后端
2501_9216494918 小时前
如何获取美股实时行情:Python 量化交易指南
开发语言·后端·python·websocket·金融
serendipity_hky19 小时前
【SpringCloud | 第5篇】Seata分布式事务
分布式·后端·spring·spring cloud·seata·openfeign
五阿哥永琪19 小时前
Spring Boot 中自定义线程池的正确使用姿势:定义、注入与最佳实践
spring boot·后端·python