标签:
Barrier(屏障)是一种自定义的同步原语(synchronization primitive),它解决了多个线程(参与者)在多个阶段之间的并发和协调问题。
1)多个参与者执行相同的几个阶段的操作
2)在每一个阶段内,多个参与者并发执行
3)一个屏障点代表一个阶段的结束
4)一个参与者运行至屏障点时被阻塞,需要等待其他参与者都到达屏障点
5)所有参与者都到达了屏障点,才可以进入下一个阶段
创建Barrier时,需要指定参与者数量。它允许动态的添加或者删除参与者。
Barrier适合多个线程执行多个阶段的操作。如果只有一个或两个阶段,可以考虑ContinueWhenAll。
下面是一个简单的例子。4个线程执行执行4个阶段。

四个阶段的代码。(每个阶段只是输出文本,表示某个阶段的某个任务结束)
private static void RunPhase1(int taskId)
{
Console.WriteLine("phase 1, task {0} completed", taskId);
}
private static void RunPhase2(int taskId)
{
Console.WriteLine("phase 2, task {0} completed", taskId);
}
private static void RunPhase3(int taskId)
{
Console.WriteLine("phase 3, task {0} completed", taskId);
}
private static void RunPhase4(int taskId)
{
Console.WriteLine("phase 4, task {0} completed", taskId);
}
Barrier代码。(定义参与者数量,以及到达屏障点所做的事情,即输出文本宝石当前阶段结束)
private static Barrier barrier = new Barrier(4, (b) =>
{
Console.WriteLine("phase {0} completed", b.CurrentPhaseNumber);
Console.WriteLine();
});
Main方法代码。(创建4个任务,执行四个阶段,每个阶段结束时调用SignalAndWait方法设立屏障点)
static void Main(string[] args)
{
var tasks = new List<Task>();
for (var i = 0; i < 4; i++)
{
tasks.Add(Task.Factory.StartNew((index) =>
{
var taskId = (int)index;
RunPhase1(taskId);
barrier.SignalAndWait();
RunPhase2(taskId);
barrier.SignalAndWait();
RunPhase3(taskId);
barrier.SignalAndWait();
RunPhase4(taskId);
barrier.SignalAndWait();
}, i));
}
var finalTask = Task.Factory.ContinueWhenAll(tasks.ToArray(), (taskList) =>
{
Task.WaitAll(taskList);
Console.WriteLine("all phases completed");
barrier.Dispose();
});
finalTask.Wait();
Console.ReadLine();
}
运行代码,查看结果。您会发现4个任务在每个阶段的完成顺序不太一样,所有任务完成后才进入下一个阶段。

参考:
本文有不妥之处,请见谅。
标签:
原文地址:http://www.cnblogs.com/everylittlebit/p/5425830.html