问题:后台有三个线程,分别循环输出A,B,C 实现使得屏幕交替输出ABC.
1.第一种方法比较简单,使用lock(obj),先声明一个多线程共享变量 比如int n-1;在lock中检查n的值,
if(n==1)
输出A,并将n 赋值2,否则,空转。在第二个后台线程中 if(n==2)
输出B,j将n=3
.一次类推,这样的虽然结果是输出了ABC 但是感觉方法并不优雅
2.方法2 采用信号量的办法,先将所有的线程进行阻塞,然后给A发送信号量,使得A线程输出一次A,接下来A向B发送信号量,然后A继续阻塞,B线程接受到信号量后输出一次B,向C发送信号量,继续阻塞
一次,以此类推
class Program
{
//定义三个信号量对三个线程进行控制
static AutoResetEvent AautoResetEvent = new AutoResetEvent(false);
static AutoResetEvent BautoResetEvent = new AutoResetEvent(false);
static AutoResetEvent CautoResetEvent = new AutoResetEvent(false);
static void ShowA()
{
for(int i=0;i<10;i++)
{
AautoResetEvent.WaitOne();
Console.Write("A");
BautoResetEvent.Set();
}
}
static void ShowB()
{
for (int i = 0; i < 10; i++)
{
BautoResetEvent.WaitOne();
Console.Write("B");
CautoResetEvent.Set();
}
}
static void ShowC()
{
for (int i = 0; i < 10; i++)
{
CautoResetEvent.WaitOne();
Console.Write("C");
AautoResetEvent.Set();
}
}
static void Main(string[] args)
{
Task.Run(()=>ShowA());
Task.Run(() => ShowB());
Task.Run(() => ShowC());
AautoResetEvent.Set();
Console.ReadLine();
}
}
AutoResetEvent 在Set后,waitOne 会接受到信号量,继续执行,并且自动执行Reset,将其状态更改为非终止状态,使得线程在执行到waitOne()时,会继续阻塞,等待信号量的到来
ManuResetEvent,在Set后,WaitOne接受到信号量,继续执行,使得其状态更改为终止状态,即waitOne()不会再此阻塞线程,除非手动调用Reset()
ManuReset会使的所有的线程继续执行,waitOne()不再阻塞,二AutoReset只会使得第一个阻塞的线程执行,终结原因还是在于ManuReset不会自动Reset,在终止状态时,waitOne()当然无法阻塞当前线程的运行。
在实际中使用AutoReset会更多一些,因为我们的需求一般都是在WaitOne() 线程阻塞,直到接受到信号量。在下次再次碰到waitOne()时,再次阻塞,等待信号量。
,