屏障

屏障

关卡是一个用户定义的同步基元,它使多个线程(称为“参与者”)可以分阶段同时参与执行一个算法。 每个参与者将执行到代码中的关卡点为止。 关卡表示一个阶段的工作结束。 当某个参与者到达关卡时,它将阻塞,直至所有参与者都已到达同一关卡为止。 在所有参与者都已到达关卡之后,您可以选择调用后期阶段操作。 在所有其他线程仍被阻塞时,单个线程可以使用此后期阶段操作来执行操作。 在执行该操作之后,所有参与者都将被取消阻塞。

添加和删除参与者

创建 Barrier 时,指定参与者的数量。 也可在任何时间动态地添加或移除参与者

出现故障的关卡

如果一个参与者未能到达关卡,则会发生死锁。 若要避免这些死锁,请使用 SignalAndWait 方法的重载来指定超时期限和取消标记。 这些重载将返回一个布尔值,每个参与者都会在它继续下一阶段之前检查该值。

后期阶段异常

如果后期阶段委托引发异常,则在 BarrierPostPhaseException 对象中包装它,然后将其传播到所有参与者。

关卡与ContinueWhenAll

当线程循环执行多个阶段时,关卡尤其有用。 如果您的代码只需要一个或两个阶段的工作,请考虑是否使用带有各种隐式联接的 System.Threading.Tasks.Task 对象

一个Demo:

using System;
using System.Text;
using System.Threading;

namespace MyConsole2
{
    class Program
    {

        static string[] words1 = new string[] { "brown", "jumped", "the", "fox", "quick" };
        static string[] words2 = new string[] { "dog", "lazy", "the", "over" };
        static string solution = "the quick brown fox jumped over the lazy dog.";

        static bool success = false;

        static Barrier barrier = new Barrier(1, //参与线程的数量
            b =>  // 要在每个阶段后执行的操作。 可以传递 null
            {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < words1.Length; i++)
            {
                sb.Append(words1[i]);
                sb.Append(" ");
            }
            for (int i = 0; i < words2.Length; i++)
            {
                sb.Append(words2[i]);
                if (i < words2.Length - 1)
                    sb.Append(" ");
            }
            sb.Append(".");
#if TRACE
            System.Diagnostics.Trace.WriteLine(sb.ToString());
#endif
            Console.CursorLeft = 0;
            Console.Write("Current phase: {0}", barrier.CurrentPhaseNumber);
            Console.WriteLine("thread ID:"+Thread.CurrentThread.ManagedThreadId);
            if (String.CompareOrdinal(solution, sb.ToString()) == 0)
            {
                success = true;
                Console.WriteLine("
The solution was found in {0} attempts", barrier.CurrentPhaseNumber); Console.WriteLine();
            }
        });

        static void Solve(string[] wordArray)
        {
            while (success==false)
            {
                Random random = new Random();
                for (int i = wordArray.Length - 1; i > 0; i--)
                {
                    int swapIndex = random.Next(i+1);
                    string temp = wordArray[i];
                    wordArray[i] = wordArray[swapIndex];
                    wordArray[swapIndex] = temp;
                }
                //等待其它参与者到达
                barrier.SignalAndWait();
            }
        }
        static void Main(string[] args)
        {
            Thread t1 = new Thread(() => Solve(words1));
            Thread t2 = new Thread(() => Solve(words2));
            barrier.AddParticipant();//添加一个参与者
            t1.Start();
            t2.Start();

            Console.ReadLine();
        }

         

    }

}

原文地址:https://www.cnblogs.com/goodlucklzq/p/4487943.html