.NET 4.0 Barrier Class
Introduction
.NET 4.0後在System.Threading命名空間中新加入了Barrier類別,該類別的功能就如同字面意義一樣,可視為是一個關卡或是剪票口。透過Barrier Class我們可以管制執行緒的運作,做到執行緒同步的效果。
字面意思
Barrier [`bærIL]
n.剪票口;海關關卡;障礙物;路障,柵欄
Support
- .NET Framework 4.0 (C# 4.0、VB.NET 10.0) or latter
Assembly
System (in System.dll)
Namespace
Barrier Class
Barrier Class在使用上十分的簡單,只要宣告Barrier物件並在建構函式帶入participantCount(簡單的說就是要等待的執行緒個數),並在要同步的點叫用SignalAndWait即可。
執行緒會在叫用SignalAndWait後會暫停運行,等待所有要參與的執行緒都到了同步點才繼續往下運行。
舉個例子來看,假設今天Charlie、Mac、Dennis三個人相約要去西雅圖喝咖啡。由於三個人的住的地區不盡相同,且車子都需要加油,因此他們約在途中會經過的加油站待會合後一同前往。
這樣的情境我們可以透過Thread與Barrier用程式加以模擬出來
VB.NET
Imports System.Threading
Module Module1
Private sync As Barrier
Sub Main(ByVal args() As String)
sync = New Barrier(3)
Dim charlie = New Thread(Sub() DriveToBoston("Charlie", TimeSpan.FromSeconds(1)))
charlie.Start()
Dim mac = New Thread(Sub() DriveToBoston("Mac", TimeSpan.FromSeconds(2)))
mac.Start()
Dim dennis = New Thread(Sub() DriveToBoston("Dennis", TimeSpan.FromSeconds(3)))
dennis.Start()
charlie.Join()
mac.Join()
dennis.Join()
Console.ReadKey()
End Sub
Sub DriveToBoston(ByVal name As String, ByVal timeToGasStation As TimeSpan)
Console.WriteLine("[{0}] Leaving House", name)
' Perform some work
Thread.Sleep(timeToGasStation)
Console.WriteLine("[{0}] Arrived at Gas Station", name)
' Need to sync here
sync.SignalAndWait()
' Perform some more work
Console.WriteLine("[{0}] Leaving for Gas Station", name)
End Sub
End Module
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace BarrierDemo
{
class Program
{
static Barrier sync;
static void Main(string[] args)
{
sync = new Barrier(3);
var charlie = new Thread(() => DriveToBoston("Charlie", TimeSpan.FromSeconds(1))); charlie.Start();
var mac = new Thread(() => DriveToBoston("Mac", TimeSpan.FromSeconds(2))); mac.Start();
var dennis = new Thread(() => DriveToBoston("Dennis", TimeSpan.FromSeconds(3))); dennis.Start();
charlie.Join();
mac.Join();
dennis.Join();
Console.ReadKey();
}
static void DriveToBoston(string name, TimeSpan timeToGasStation)
{
Console.WriteLine("[{0}] Leaving House", name);
// Perform some work
Thread.Sleep(timeToGasStation);
Console.WriteLine("[{0}] Arrived at Gas Station", name);
// Need to sync here
sync.SignalAndWait();
// Perform some more work
Console.WriteLine("[{0}] Leaving for Gas Station", name);
}
}
}
若是不使用Barrier去同步,這邊我們可以拿掉sync.SignalAndWait()再做一次運行,則三個人就會變成各自前往西雅圖喝咖啡了。