C# 多线程之同步输出奇偶数
在论坛上见有人说有这么个经典的面试题,我也来说说,^_^
此题涉及到:多线程,同步,排他
那前面顺便讲一下两个排他应用的AutoResetEvent与ManualResetEvent的区别
AutoResetEvent:通知正在等待的线程已发生事件
ManualResetEvent :通知一个或多个正在等待的线程已发生事件
它们常用的三个事件有:
1)Set(); 2)ReSet(); 3)WaitOne();
字面上来说,一个是自动,一个是手动,其最跟本的区别是
一.AutoResetEvent的Set()只允许一个线程运行.也就是说AutoResetEvent的Set()方法,只会使一个线程得到运行,而使其它处于
WaitOne()状态的线程自动为ReSet()的无信号状态.
二.而ManualResetEvent 的Set()则不会使处于WaitOne()状态的线程自动为ReSet()的无信号状态.如果想其处于无信号状态,必须手动调用ReSet()方法.
//-----------------------------------------------------------------------
下面就直接给代码了
using System;
using System.Collections.Generic;
using System.Threading;
using System.IO;
namespace ThreadTest
{
#region main
class Program
{
static void Main(string[] args)
{
TheadTest th = new TheadTest();
th.Start();
Console.ReadKey();
}
}
/// <summary>
/// 定义一个线程类
/// </summary>
class TheadTest
{
//定义一个Stream对象接收打开文件
private FileStream st;
//构造方法
public TheadTest()
{
}
public void Start()
{
//定义两个信号锁
AutoResetEvent ateA = new AutoResetEvent(false);
AutoResetEvent ateB = new AutoResetEvent(false);
//把信号锁加入到List中
List<AutoResetEvent> lst = new List<AutoResetEvent>();
lst.Add(ateA);
lst.Add(ateB);
//定义带参数的输出偶数线程
Thread thrEven = new Thread(new ParameterizedThreadStart(OutPutEven));
//把两个信号锁传入线程
thrEven.Start(lst);
//定义带参数的输出奇数线程
Thread thrOdd = new Thread(new ParameterizedThreadStart(OutPutOdd));
thrOdd.Start(lst);
}
private void OutPutEven(object lst)
{
AutoResetEvent ateA = (lst as List<AutoResetEvent>)[0];
AutoResetEvent ateB = (lst as List<AutoResetEvent>)[1];
for (int i = 0; i < 100; i += 2)
{
//设置本线程为无信号
ateA.WaitOne();
//输出
Console.WriteLine(i);
//st = File.Open(@"C:\file.txt", FileMode.Open); //用来测试同时访问文件系统的
//st.Close();
ateB.Set(); //设置输出奇数线程有信号
//Thread.Sleep(500);
}
}
private void OutPutOdd(object lst)
{
AutoResetEvent ateA = (lst as List<AutoResetEvent>)[0];
AutoResetEvent ateB = (lst as List<AutoResetEvent>)[1];
//设置偶数线程先输出
ateA.Set();
for (int i = 1; i < 100; i += 2)
{
//设置本线程为无信号
ateB.WaitOne();
Console.WriteLine(i);
//st = File.Open(@"C:\file.txt", FileMode.Open); //用来测试同时访问文件系统的
//st.Close();
ateA.Set(); //设置输出偶数线程有信号
//Thread.Sleep(500);
}
}
}
#endregion main
}
转载于:https://blog.51cto.com/fengbo1983/507094