Java如何保证线程T1,T2,T3 顺序执行?

news2024/10/12 2:12:02

文章目录

      • 方案 1:使用 `Thread.join()`
      • 方案 2:使用 `Lock` 和 `Condition`
      • 方案 3:使用 `CyclicBarrier`
      • 方案 4:使用 `Semaphore`
      • 总结

博主介绍:全网粉丝10w+、CSDN合伙人、华为云特邀云享专家,阿里云专家博主、星级博主,51cto明日之星,热爱技术和分享、专注于Java技术领域
🍅文末获取源码联系🍅
👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟

在 Java 中,要确保线程 T1、T2 和 T3 顺序执行,可以使用多种方式。这里介绍几种常见的方案:
在这里插入图片描述

方案 1:使用 Thread.join()

Thread.join() 是最简单直接的方法。调用某个线程的 join() 方法时,当前线程会等待该线程执行完毕后再继续执行。

代码示例:

public class ThreadSequence {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            System.out.println("Thread T1 is running.");
        });

        Thread t2 = new Thread(() -> {
            System.out.println("Thread T2 is running.");
        });

        Thread t3 = new Thread(() -> {
            System.out.println("Thread T3 is running.");
        });

        try {
            t1.start();
            t1.join(); // 等待 t1 结束
            t2.start();
            t2.join(); // 等待 t2 结束
            t3.start();
            t3.join(); // 等待 t3 结束
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在这种方式中,主线程依次启动并等待 T1、T2 和 T3 执行完毕,确保了线程顺序执行。

方案 2:使用 LockCondition

通过 ReentrantLockCondition,我们可以更灵活地控制线程的执行顺序。Condition 提供了 await()signal() 方法,可以实现线程之间的精确控制。

代码示例:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadSequenceLock {
    private static Lock lock = new ReentrantLock();
    private static Condition conditionT2 = lock.newCondition();
    private static Condition conditionT3 = lock.newCondition();
    private static boolean t1Finished = false;
    private static boolean t2Finished = false;

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            lock.lock();
            try {
                System.out.println("Thread T1 is running.");
                t1Finished = true;
                conditionT2.signal(); // 通知 T2 开始
            } finally {
                lock.unlock();
            }
        });

        Thread t2 = new Thread(() -> {
            lock.lock();
            try {
                while (!t1Finished) {
                    conditionT2.await(); // 等待 T1 完成
                }
                System.out.println("Thread T2 is running.");
                t2Finished = true;
                conditionT3.signal(); // 通知 T3 开始
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });

        Thread t3 = new Thread(() -> {
            lock.lock();
            try {
                while (!t2Finished) {
                    conditionT3.await(); // 等待 T2 完成
                }
                System.out.println("Thread T3 is running.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });

        t1.start();
        t2.start();
        t3.start();
    }
}

在这个示例中,通过 ReentrantLockCondition 来控制 T2 等待 T1 完成,T3 等待 T2 完成,实现线程的顺序执行。

方案 3:使用 CyclicBarrier

CyclicBarrier 允许多个线程在某个点上进行同步。可以通过它来确保线程之间按顺序执行。

代码示例:

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class ThreadSequenceBarrier {
    public static void main(String[] args) {
        CyclicBarrier barrier1 = new CyclicBarrier(2); // 控制 T2 等待 T1
        CyclicBarrier barrier2 = new CyclicBarrier(2); // 控制 T3 等待 T2

        Thread t1 = new Thread(() -> {
            System.out.println("Thread T1 is running.");
            try {
                barrier1.await(); // 让 T2 继续执行
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                barrier1.await(); // 等待 T1 先执行
                System.out.println("Thread T2 is running.");
                barrier2.await(); // 让 T3 继续执行
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });

        Thread t3 = new Thread(() -> {
            try {
                barrier2.await(); // 等待 T2 先执行
                System.out.println("Thread T3 is running.");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });

        t1.start();
        t2.start();
        t3.start();
    }
}

在此方案中,CyclicBarrier 用于确保线程在特定的同步点等待其他线程达到,从而实现线程按顺序执行。

方案 4:使用 Semaphore

Semaphore 信号量可以控制多个线程对共享资源的访问权限。通过设置初始许可数量,我们可以用它来控制线程的执行顺序。

代码示例:

import java.util.concurrent.Semaphore;

public class ThreadSequenceSemaphore {
    public static void main(String[] args) {
        Semaphore semaphoreT1 = new Semaphore(1); // 控制 T1 的执行
        Semaphore semaphoreT2 = new Semaphore(0); // 控制 T2 的执行
        Semaphore semaphoreT3 = new Semaphore(0); // 控制 T3 的执行

        Thread t1 = new Thread(() -> {
            try {
                semaphoreT1.acquire(); // 先获取许可
                System.out.println("Thread T1 is running.");
                semaphoreT2.release(); // 释放 T2 的许可
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                semaphoreT2.acquire(); // 等待 T1 释放许可
                System.out.println("Thread T2 is running.");
                semaphoreT3.release(); // 释放 T3 的许可
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t3 = new Thread(() -> {
            try {
                semaphoreT3.acquire(); // 等待 T2 释放许可
                System.out.println("Thread T3 is running.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        t1.start();
        t2.start();
        t3.start();
    }
}

在这个例子中,信号量控制线程执行的先后顺序,确保 T1 先执行,T2 再执行,最后 T3 执行。

总结

为了确保线程 T1、T2 和 T3 按顺序执行,常用的方法包括使用 Thread.join()LockConditionCyclicBarrier 以及 Semaphore。选择哪种方案取决于具体的应用场景和需求:

  • 如果简单且直接,Thread.join() 是最合适的。
  • 如果需要更复杂的线程控制,可以考虑 LockConditionCyclicBarrierSemaphore 等同步工具。

大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2206579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初始操作系统篇(1)—— 操作系统的概念与分类

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: 操作系统 目录 操作系统的基本概念 操作系统的概念 操作系统的特征 并发 共享 虚拟 异步 操作系统的目标和功能 操作系统的发展与分…

T11:优化器对比实验

T11周:优化器对比实验 **一、前期工作**1.设置GPU,导入库 **二、数据预处理**1.导入数据2.检查数据3.配置数据集4.数据可视化 **三、构建模型****四、训练模型****五、模型评估**六、总结 🍨 本文为🔗365天深度学习训练营 中的学习记录博客&a…

QT实现Opencv图像处理

案例 基于QT的人脸识别 pro文件需要加以下代码 INCLUDEPATH E:/opencv/opencv3.4-qt-intall/install/include INCLUDEPATH E:/opencv/opencv3.4-qt-intall/install/include/opencv INCLUDEPATH E:/opencv/opencv3.4-qt-intall/install/include/opencv2 LIBS E:/opencv/o…

Linux go语言配置

首先安装go语言 先从go官方下载源码 解压: tar -xzvf go1.23.1.linux-amd64.tar.gz 移动go到 /usr/local/ mv go /usr/local 设置环境变量 vi ~/.bashrc source ~/.bashrc 重新获取文件 输入 go version 查看版本

STM32 A/D转换器

目录 模拟量输入通道 A/D转换器简介 模拟量输入信号类型与量程自动转换 量程自动转换 STM32F103ZET6集成的ADC模块 STM32的ADC的主要特征 STM32的ADC模块结构 ADC中断事件主要有以下3个: 模拟量输入通道 模拟量输入通道一般由信号处理、模拟开关、放大器、采…

MES管理系统解决方案常见的应用场景

在现代制造业的浪潮中,车间管理的效率与智能化水平成为了企业竞争力的关键因素。许多车间管理者都耳闻MES管理系统解决方案能够显著优化生产执行流程,但由于缺乏亲身体验,往往对此持保留态度。那么,MES管理系统究竟能否如传闻般发…

po框架的了解和应用

https://www.cnblogs.com/xiaolehong/p/18458470 笔记 任务:1、通过po框架输入测试报告 2、编写自动化测试框架 3、总结测试讲解稿 自动化测试框架概念: 自动化测试框架是一个集成体系,这个体系中包含测试功能的函数、测试数据源、测试对以及重要的模块。 作用:用于解决或…

MIDIPLUS 50周年丨中国国际乐器展览会首日盛况

10月10日,由中国乐器协会、上海国展展览中心有限公司、法兰克福展览(上海)有限公司共同主办的中国(上海)国际乐器展览会在上海新国际博览中心(上海市浦东新区龙阳路2345号)盛大开幕。 2024上海…

ART 光学跟踪系统:通过 VR HMD 解锁完全沉浸式 VR 体验

在虚拟现实体验中,完全沉浸式虚拟现实体验应该既准确又舒适。当与现实世界的物体融合时,虚拟现实的表现必须与现实精确匹配。这意味着所使用的运动跟踪系统必须为整套项目提供可靠且可重复的高精度运动数据,以及体感无法察觉到的超低延迟。AR…

水深探测仪的作用和使用方法

在水域救援的行动里,救援人员时刻面临着复杂多变、充满未知的水域状况。当接到救援任务奔赴现场,那片需要涉足的水域就像一个神秘莫测的异世界,挑战着所有人的认知与勇气。 水深探测仪作为一种专用于测量水域深度的设备,通过声波和…

宝塔 进程守护管理器 神坑,再次跌入。thinkphp-queue队列 勤勤学长

如果,你有在使用【进程守护管理器】,记得在更新/重启,甚至卸载重新安装后,重启服务器。 事情的起因是,昨日服务器突然异常,网站无法正常访问,进入宝塔面板,发现 cpu和负载率均超过1…

甘肃小米,一口软糯,满是乡愁

🎈甘肃小米,自然的馈赠🎈🌾家人们,今天必须给大家安利来自甘肃的小米!💛✨甘肃,那片广袤而神奇的土地,孕育出的小米有着别样的魅力。颗粒饱满,色泽金黄&#…

RDD优化:缓存和checkpoint机制、数据共享(广播变量、累加器)、RDD的依赖关系、shuffle过程、并行度说明

文章目录 1. 缓存和checkpoint机制1.1 缓存使用1.2 checkpoint1.3 缓存和checkpoint的区别 2. 数据共享2.1 广播变量2.2 累加器 3. RDD依赖关系4.shuffle过程4.1 shuffle介绍4.2 spark计算要尽量避免shuffle 5. 并行度 1. 缓存和checkpoint机制 缓存和checkpoint也叫作rdd的持…

源代码加密有哪些技巧呢?除了用加密软件还有哪些方法?

导语:源代码加密是保护软件核心资产的主要方式了,可以通过多种技术措施确保源代码不被未授权访问、复制或篡改,防止泄密问题。这篇文章是一些有效的源代码加密技巧,欢迎您的阅读! 源代码加密常用技巧1、访问控制&…

俏生元将传统膳食智慧融入现代生活,自然成分绽放健康光彩

近年来,当代女性健康食品市场正经历快速发展和显著变化。随着女性健康意识的提升,市场对专门针对女性健康的产品需求快速上升。女性消费者对健康的关注不再局限于表面,而是越来越注重内在健康和生活质量的提升。此外,中式养生文化…

Python 基于 Bert 的中文情歌分析,多分类中文情感分析

前言 在自然语言处理(NLP)领域中,情感分析是一项非常常见的任务。它的目标是判断文本的情感倾向,例如在社交媒体上的评论、产品评价、电影评论等数据中,识别文本是正面的、负面的,还是中性的。与传统的二分…

中航资本:科技股有哪几种?科技股都包含哪些板块?

科技股主要有两种,一种是软科技,一种是硬科技。 1、硬科技:需要强健的数学、物理、计算机科学和工程技能才能够完毕,例如:光电芯片、‌人工智能、‌航空航天、‌生物技能、‌信息技能、计算机视觉、集成电路规划、软件…

2024双十一值得入手的好物品牌有哪些?精选五款双十一必入好物推荐

在双十一这个全民狂欢的购物节,各大品牌纷纷推出诱人的优惠活动,让人心动不已。今年,有哪些品牌的好物值得我们关注呢?下面,我将为大家精选五款双十一必入好物推荐,让你的购物车不再空虚。 双十一必入好物…

怎么把人声和背景音乐分离?实用方法:将人声从音乐中剥离

怎么把人声和背景音乐分离?在数字音频处理中,将人声与背景音乐进行分离是一个复杂但富有挑战性的任务。这种分离技术在音乐制作、影视编辑、版权管理以及个人娱乐等多个领域具有广泛的应用价值。 虽然完美地将人声和背景音乐分离开来可能仍然是一个技术难题&#…

⽂件操作详解

本章讲述的是有关文件的相关内容,本章我们会认识到什么是文件,二进制文件与文本文件,文件的打开和关闭,⽂件的顺序读写和随机读写以及⽂件读取结束的判定和⽂件缓冲区。 1.什么是⽂件 像这样在磁盘(硬盘)上…