zoukankan      html  css  js  c++  java
  • Barrier Class Usage(Synchronization of .net 4.0)

    The Barrier class is a signaling construct new to Framework 4.0. It implements a thread execution barrier, which allows many threads to rendezvous at a point in time. The class is very fast and efficient, and is built upon Wait, Pulse, and spinlocks.

    To use this class:

    1. Instantiate it, specifying how many threads should partake in the rendezvous (you can change this later by calling AddParticipants/RemoveParticipants).
    2. Have each thread call SignalAndWait when it wants to rendezvous.

    Instantiating Barrier with a value of 3 causes SignalAndWait to block until that method has been called three times. But unlike a CountdownEvent, it then automatically starts over: calling SignalAndWait again blocks until called another three times. This allows you to keep several threads “in step” with each other as they process a series of tasks.

     

    In the following example, each of three threads writes the numbers 0 through 4, while keeping in step with the other threads:

    static Barrier _barrier = new Barrier (3);   
    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();   } } 
    0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 

    A really useful feature of Barrier is that you can also specify a post-phase action when constructing it. This is a delegate that runs after SignalAndWait has been called n times, but before the threads are unblocked. In our example, if we instantiate our barrier as follows:

    static Barrier _barrier = new Barrier (3, barrier => Console.WriteLine()); 

    then the output is:

    0 0 0  
    1 1 1  
    2 2 2  
    3 3 3  
    4 4 4  

    A post-phase action can be useful for coalescing data from each of the worker threads. It doesn’t have to worry about preemption, because all workers are blocked while it does its thing. 

    Another way of Explaination

    Visual Studio 2010 and .NET Framework 4 Training Kit中有个System.Threading.Barrier的Demo,通过Barrier Class我们可以控制线程的运行,做到线程同步的效果。

    Barrier Class在使用上十分的简单,只要在Barrier的构造函数中传入participantCount(简单的说就是要等待的线程个数),并在要同步的点调用SignalAndWait方法就可以了。线程会在调用SignalAndWait之后暂停运行,等待所有参与的线程都到达了同步点才继续往下运行。 

     

    举个例子来看,假设今天Charlie、Mac、Dennis三个人相约要去西雅图喝咖啡。由于三个人的住的地区不尽相同,且车子都需要加油,因此他们约在途中会经过的加油站待会合后一同前往。这样的情境我们可以通过Thread与Barrier用程序仿真出来。

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Threading;

    namespace BarrierDemo 

        class Program 
        { 
            static Barrier sync; 
            static CancellationToken token;

            static void Main(string[] args) 
            { 
                var source = new CancellationTokenSource(); 
                token = source.Token; 
                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();

                //source.Cancel();

                charlie.Join(); 
                mac.Join(); 
                dennis.Join();

                Console.ReadKey(); 
            }

            static void DriveToBoston(string name, TimeSpan timeToGasStation) 
            { 
                try 
                { 
                    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(token);

                    // Perform some more work 
                    Console.WriteLine("[{0}] Leaving for Boston", name); 
                } 
                catch (OperationCanceledException) 
                { 
                    Console.WriteLine("[{0}] Caravan was cancelled! Going home!", name); 
                } 
            } 
        } 

    } 

  • 相关阅读:
    android 75 新闻列表页面
    android 74 下载文本
    android 73 下载图片
    android 72 确定取消对话框,单选对话框,多选对话框
    android 71 ArrayAdapter和SimpleAdapter
    android 70 使用ListView把数据显示至屏幕
    maven如何将本地jar安装到本地仓库
    Centos6.7搭建ISCSI存储服务器
    解决maven打包编译出现File encoding has not been set问题
    MySQL 解决 emoji表情 的方法,使用utf8mb4 字符集(4字节 UTF-8 Unicode 编码)
  • 原文地址:https://www.cnblogs.com/malaikuangren/p/2534748.html
Copyright © 2011-2022 走看看