4、多线程-通过 N 个线程顺序循环打印从 0 至 100

题目

通过 N 个线程顺序循环打印从 0 至 100

代码示例

using System;
using System.Threading;
using System.Threading.Tasks;

public class ZeroEvenOdd
{
	private int n = 100;
	private AutoResetEvent zeroEvent = new AutoResetEvent(true); // 一开始 zero 可以运行
	private AutoResetEvent evenEvent = new AutoResetEvent(false);
	private AutoResetEvent oddEvent = new AutoResetEvent(false);

	public ZeroEvenOdd(int n)
	{
		this.n = n;
	}

	public void Zero(Action<int> printNumber)
	{
		for (int i = 0; i <= n; i++)
		{
			zeroEvent.WaitOne(); // 等待 zero 事件
			printNumber(0); // 打印 0

			if (i % 2 == 0)
			{
				evenEvent.Set(); // 如果 i 是偶数,唤醒 even 线程
			}
			else
			{
				oddEvent.Set(); // 如果 i 是奇数,唤醒 odd 线程
			}
		}
	}

	public void Even(Action<int> printNumber)
	{
		for (int i = 0; i <= n; i++)
		{
			evenEvent.WaitOne(); // 等待 even 事件
			if (i <= n && i % 2 == 0)
			{
				printNumber(i); // 打印偶数
			}
			zeroEvent.Set(); // 唤醒 zero 线程
		}
	}

	public void Odd(Action<int> printNumber)
	{
		for (int i = 0; i <= n; i++)
		{
			oddEvent.WaitOne(); // 等待 odd 事件
			if (i <= n && i % 2 != 0)
			{
				printNumber(i); // 打印奇数
			}
			zeroEvent.Set(); // 唤醒 zero 线程
		}
	}

	public static void Main(string[] args)
	{
		int n = 100;
		ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(n);

		var zeroTask = Task.Run(() => zeroEvenOdd.Zero(Console.Write));
		var evenTask = Task.Run(() => zeroEvenOdd.Even(Console.Write));
		var oddTask = Task.Run(() => zeroEvenOdd.Odd(Console.Write));

		Task.WaitAll(zeroTask, evenTask, oddTask);
		Console.WriteLine();
	}
}
posted @ 2024-12-14 11:33  似梦亦非梦  阅读(11)  评论(0编辑  收藏  举报