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();
}
}