三种方法教你实现多线程交替打印ABC,干货满满!

简介: 本文介绍了多线程编程中的经典问题——多线程交替打印ABC。通过三种方法实现:使用`wait()`和`notify()`、`ReentrantLock`与`Condition`、以及`Semaphore`。每种方法详细讲解了实现步骤和代码示例,帮助读者理解和掌握线程间的同步与互斥,有效解决并发问题。适合不同层次的开发者学习参考。



Hello,大家好,我是你们活力四射的技术小伙伴小米!今天我们继续实战算法系列的主题,来聊一聊多线程编程中的一个经典问题——多线程交替打印ABC。

问题背景

假设有三个线程,分别打印字母A、B、C。我们需要让这三个线程交替运行,按顺序打印出“ABCABCABC...”,直到打印一定次数或者满足某个条件。如何通过多线程的协调实现这个任务呢?这听起来简单,实际涉及到线程之间的同步和互斥,是我们学习多线程编程的一个很好的练习。

多线程编程的挑战

在多线程编程中,最大的问题就是如何控制多个线程的执行顺序。线程是并发执行的,也就是说它们的执行顺序在没有约束的情况下是不可预知的。为了确保多个线程按照我们期望的顺序执行,就需要使用一些同步机制,比如锁、条件变量、信号量等。

接下来,我会带大家用三种方式来实现这个任务。我们会分别使用Objectwait()notify()方法、ReentrantLockCondition、以及信号量来实现多线程交替打印ABC。

方案一:使用wait()和notify()

首先,最常用的一种方法是利用Java中Object类自带的wait()notify()方法来实现线程之间的同步。每个线程在完成它的打印任务后,通知下一个线程开始执行。

实现步骤

  1. 定义一个共享对象用来同步。
  2. 使用wait()让线程进入等待状态。
  3. 使用notify()唤醒下一个线程。

实现代码

运行结果

在这个实现中,我们使用了wait()notifyAll()方法来控制线程的执行顺序。每个线程在不该自己执行的时候调用wait()方法进入等待状态,直到被下一个线程通过notifyAll()方法唤醒。

方案二:使用ReentrantLock和Condition

第二种方法是使用ReentrantLockCondition类。ReentrantLock是Java中更高级的锁机制,可以控制多个条件变量,而Condition则可以用来替代wait()notify()的功能。

实现步骤

  1. 定义一个ReentrantLock和多个Condition
  2. 每个线程等待相应的Condition,当符合条件时打印字符并唤醒下一个线程。

实现代码

运行结果

在这个实现中,我们使用ReentrantLockCondition来替代了wait()notify()。通过lock来确保线程安全,通过Condition来控制每个线程的执行顺序。

方案三:使用信号量

最后一种方法是使用Semaphore类。Semaphore是一个计数信号量,可以控制多个线程之间的协调。这里,我们使用三个信号量,分别控制线程A、B、C的执行。

实现步骤

定义三个信号量semA、semB、semC

每个线程在自己的信号量上等待,打印完成后释放下一个线程的信号量。

实现代码

运行结果

在这个实现中,信号量控制了线程的执行顺序。初始时,semA的计数为1,而semBsemC为0,这保证了线程A先运行,然后通过释放信号量来依次唤醒线程B和C。

END

今天我们学习了三种实现多线程交替打印ABC的方法:使用wait()notify(),使用ReentrantLockCondition,以及使用信号量。通过这些方法,我们可以有效地控制线程之间的同步与互斥,解决复杂的并发问题。

这三种方法各有优劣。wait()notify()较为基础,适合简单的场景;ReentrantLockCondition提供了更细粒度的控制,适合复杂的并发场景;而Semaphore则是一种经典的计数信号量机制,在某些场景下显得更加直观和高效。

希望这篇文章对大家理解多线程编程有所帮助!如果大家有其他问题或者想要了解更多,欢迎在评论区讨论哦!咱们下次见啦~

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号软件求生,获取更多技术干货!

相关文章
|
3月前
|
存储 Oracle Java
|
5月前
|
Java
创建线程的方法
Java中实现多线程有四种方式:1. 继承Thread类,简单但占用继承机会,耦合度高;2. 实现Runnable接口,推荐方式,任务与线程解耦,支持Lambda;3. 实现Callable接口配合FutureTask,可获取返回值和异常;4. 使用线程池(ExecutorService),企业推荐,管理线程生命周期,提升性能,支持多种线程池类型。
149 1
|
6月前
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
414 5
|
监控 Java
捕获线程执行异常的多种方法
【10月更文挑战第15天】捕获线程执行异常的方法多种多样,每种方法都有其特点和适用场景。在实际开发中,需要根据具体情况选择合适的方法或结合多种方法来实现全面有效的线程异常捕获。这有助于提高程序的健壮性和稳定性,减少因线程异常带来的潜在风险。
290 57
|
12月前
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法
|
12月前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
251 3
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
142 2
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
188 1
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
318 1

热门文章

最新文章