三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC....”的字符串
using System; using System.Threading; class PrintThread { private string text; private int count; private Semaphore semaphore; private Semaphore nextSemaphore; public PrintThread(string text, int count, Semaphore semaphore, Semaphore nextSemaphore) { this.text = text; this.count = count; this.semaphore = semaphore; this.nextSemaphore = nextSemaphore; } public void Run() { for (int i = 0; i < count; i++) { semaphore.WaitOne(); // 等待信号量 Console.Write(text); nextSemaphore.Release(); // 释放下一个线程的信号量 } } } class Program { static void Main(string[] args) { Semaphore semaphoreA = new Semaphore(1, 1); Semaphore semaphoreB = new Semaphore(0, 1); Semaphore semaphoreC = new Semaphore(0, 1); int n = 10; // 打印 n 次 PrintThread threadA = new PrintThread("A", n, semaphoreA, semaphoreB); PrintThread threadB = new PrintThread("B", n, semaphoreB, semaphoreC); PrintThread threadC = new PrintThread("C", n, semaphoreC, semaphoreA); Thread t1 = new Thread(threadA.Run); Thread t2 = new Thread(threadB.Run); Thread t3 = new Thread(threadC.Run); t1.Start(); t2.Start(); t3.Start(); t1.Join(); t2.Join(); t3.Join(); } }
这段代码中,我们使用了信号量(Semaphore)来控制线程的执行顺序。在主程序中,我们创建了三个信号量semaphoreA
、semaphoreB
和semaphoreC
,分别用于控制线程 A、B、C 的执行顺序。
然后,我们创建了三个PrintThread
对象,分别表示打印 A、B、C 的线程。每个线程的构造函数中,都传入了它自己的信号量semaphore
和下一个线程的信号量nextSemaphore
。
在每个线程的Run
方法中,首先等待自己的信号量,表示它需要等待前一个线程完成打印。然后,它打印自己的字符,并释放下一个线程的信号量,表示下一个线程可以开始打印。
在主程序中,我们创建了三个Thread
对象t1
、t2
和t3
,分别对应线程 A、B、C,然后启动这三个线程并等待它们执行完毕。最终输出的结果是形如“ABCABCABC....”的字符串,共打印了 n 次。

public class PrintABC implements Runnable { private String name; private int count; private Object lock; private int currentCount; public PrintABC(String name, int count, Object lock, int currentCount) { this.name = name; this.count = count; this.lock = lock; this.currentCount = currentCount; } public void run() { while (true) { synchronized (lock) { while (currentCount % 3 != 0 && name.equals("A")) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } while (currentCount % 3 != 1 && name.equals("B")) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } while (currentCount % 3 != 2 && name.equals("C")) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if (currentCount >= count * 3) { break; } System.out.print(name); currentCount++; lock.notifyAll(); } } } public static void main(String[] args) { int count = 5; Object lock = new Object(); new Thread(new PrintABC("A", count, lock, 0)).start(); new Thread(new PrintABC("B", count, lock, 1)).start(); new Thread(new PrintABC("C", count, lock, 2)).start(); }
在这段代码中,我们创建了一个`PrintABC`类来表示每个线程。构造函数接收线程的名称、计数值、锁对象和当前计数器的值。在`run()`方法中,我们使用`synchronized`关键字来确保线程之间的同步。线程会循环打印字母,并根据当前计数器的值判断该线程是否需要打印字母。在每次打印完字母后,线程会通知所有等待该锁的线程继续执行,以便下一个线程打印字母。如果计数器超过了给定的计数值,则线程会退出循环。
在主程序中,我们创建了一个锁对象和三个`PrintABC`对象,分别代表线程 A、B、C。然后,我们启动每个线程,并传递当前计数器的值,以便线程可以判断是否需要打印字母。每个线程在打印完字母后,会通知下一个线程继续执行,直到所有线程完成任务并退出。最终,输出的字符串形如“ABCABCABC...”。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!