深入多線程之:解析線程的交會(Thread Rendezvous)詳解
在上篇文章中我們使用了Wait和Pulse 實(shí)現(xiàn)了Countdown
接下來我們可以使用剛剛寫的Countdown 類來實(shí)現(xiàn)兩個線程的交會。
class Rendezvous
{
static object _locker = new object();
static Countdown _countdown = new Countdown(2);
public static void MainThread()
{
Random r = new Random();
new Thread(Mate).Start(r.Next(1000));
Thread.Sleep(r.Next(10000)); //主線程睡眠一段時間
_countdown.Singnal(); //向_countdown注冊信號,告知主線程已經(jīng)來了。
_countdown.Wait(); //等待其他線程
Console.WriteLine("Mate!");
}
static void Mate(object delay)
{
Thread.Sleep((int)delay);//線程睡眠。
_countdown.Singnal(); //向_countdown注冊信號,告知線程已經(jīng)來了。
_countdown.Wait(); //等待其他線程。
Console.WriteLine("Mate!");
}
}
就像小時候去春游一樣,這里的_countdown就是老師,線程就是學(xué)生。
學(xué)生A早上睡覺,然后起床來到交會點(diǎn),然后告訴老師,我來了,接著等待老師的出發(fā)命令,因?yàn)槔蠋熤烙袃蓚€學(xué)生要去春游,所以現(xiàn)在只來了一個,還有一個沒有來,所以老師會讓學(xué)生A等待,阻塞。
學(xué)生B也是睡覺,接著也來到交會點(diǎn),告訴老師,我也來了,然后等待老師的出發(fā)命令。
當(dāng)學(xué)生B告訴老師我來了的時候,此時老師的剩余等待學(xué)生計(jì)數(shù)為0,所以老師告訴這兩個學(xué)生,你們可以出發(fā)了。
.net framework 4.0 提供了Barrier 的構(gòu)造來實(shí)現(xiàn)線程交會的功能。如圖所示:

Thread1 調(diào)用SignalAndWait告知Barrier,我已經(jīng)來了,然后阻塞。
Thread3調(diào)用SignalAndWait告知Barrier,我已經(jīng)來了,然后阻塞。
Thread2 調(diào)用SignalAndWait告知Barrier,我已經(jīng)來了,Barrier知道現(xiàn)在三個線程都來了,所以讓他們繼續(xù)并發(fā)執(zhí)行。
Barrier的方法簡介:
AddParticipants:增加參與者,也就是增加春游的人數(shù)。
RemoveParticipant:減少參與者,可能某人肚子痛,不能參加春游了。
SignalAndWait :參與者已經(jīng)來了,并等待其他參與者的到來。
下面是使用Barrier的示例:
static Barrier _barrier = new Barrier(3);//說明有三個參與者
public static void Main()
{
new Thread(Speak).Start();
new Thread(Speak).Start();
new Thread(Speak).Start();
}
static void Speak()
{
for (int i = 0; i < 5; i++)
{
Console.Write(i + " ");
_barrier.SignalAndWait(); //告知參與者已經(jīng)來了,等待其他參與者
}
}
輸出如下:
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4
Barrier 的另一個非常有用的特性是在每一個階段完成的時候你都可以執(zhí)行一個post-phase 的action委托。
什么是階段呢??,階段就是參與者全部都到了的時候。
如果我們修改Barrier的構(gòu)造函數(shù)如下:
static Barrier _barrier = new Barrier(3, (barrier) => Console.WriteLine());
//說明有三個參與者,并且每次三個參與者完成任務(wù)的時候執(zhí)行Console.WriteLine方法.
那么我們的輸出如下所示:
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
相關(guān)文章
Unity使用EzySlice實(shí)現(xiàn)模型多邊形順序切割
這篇文章主要為大家詳細(xì)介紹了Unity使用EzySlice實(shí)現(xiàn)模型多邊形順序切割,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07
C#中Array與ArrayList用法及轉(zhuǎn)換的方法
C#中Array與ArrayList用法及轉(zhuǎn)換的方法,需要的朋友可以參考一下2013-03-03
C#實(shí)現(xiàn)塊狀鏈表的項(xiàng)目實(shí)踐
這篇文章主要介紹了C#實(shí)現(xiàn)塊狀鏈表的項(xiàng)目實(shí)踐,通過定義塊和鏈表類,利用塊內(nèi)元素引用實(shí)現(xiàn)塊與塊之間的鏈接關(guān)系,從而實(shí)現(xiàn)對塊狀鏈表的遍歷、插入和刪除等操作,感興趣的可以了解一下2023-11-11

