《C#高级编程》读书笔记(十五):任务、线程和同步之四 同步

时间:2022-09-10 18:32:46

    lock语句,Interlocked类和Monitor类可用于进程内部的同步。Mutex类、Event类、SemaphoreSlim类和ReaderWriterLockSlim类提供个过个线程之间的线程同步。

1,Interlocked类

    Interlocked类用于使变量的简单语句原子化。Interlocked类提供了以线程安全的方式递增、递减、交换和读取值的办法。

public int State
        {
            get
            {
                lock (this)
                {
                    return ++state;
                }
            }
        }

    上面的语句可以用以下语句替代:

public int State
        {
            get
            {
                return Interlocked.Increment(ref state);
            }
        }

2,Monitor类

    lock语句由C#编译器解析为使用Monitor类。下面的lock语句:

        lock(obj)
        {
            //synchroinzed region for obj
        }

    被解析为调用Enter()方法。

            Monitor.Enter(obj);
            try
            {
                //synchroinzed region for obj
            }
            finally
            {
                Monitor.Exit(obj);
            }

    与C#的lock语句相比,Monitor类的主要优点是:可以添加一个等待被锁定的超时值。

            bool lockTaken = false;
            Monitor.TryEnter(obj, 500, ref lockTaken);
            if (lockTaken)
            {
                try
                {
                    //acquired the lock
                    //synchronized region for obj
                }
                finally
                {
                    Monitor.Exit(obj);
                }
            }
            else
            {
                //did't get the lock,do something else
            }

3,SpinLock结构

    如果基于对象的锁定对象(Monitor)的系统开销由于垃圾回收而过高,就可以使用SpinLock结构。如果有大量的锁定,且锁定的时间总是非常短,SpinLock结构就很有用。

4,Mutex类

    Mutex(mutual exclusion,互斥)是.NET Framework中提供跨多个进程同步访问的一个类。

5,Semaphore类

    信号量非常类似于互斥,其区别是,信号量可以同时由多个线程使用。信号量使用计数的互斥锁定。使用信号量,可以定义允许同时访问受旗语锁定保护的资源的线程个数。如果需要限制可以访问可用资源的线程数,信号量就很有用。例如,如果系统有3个物理端口可用,就可以允许3个线程同时访问I/O端口,但第4个线程需要等待前3个线程中的一个释放资源。

6,Events类

    与互斥和信号量对象一样,事件也是一个系统范围内的资源同步方法。可以使用事件通知其他任务:这里有一些数据,并完成了一些操作等。事件可以发信号,也可以不发信号。