多线程的锁

1.Monitor类

   Monitor.Enter和Monitor.Exit; 锁静态对象,类级的。并行的线程,串行的获得资源。

用法:

class Program
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            Thread t = new Thread(Run);

            t.Start();
        }
    }

    //资源
    static object obj = new object();

    static int count = 0;

    static void Run()
    {
        Thread.Sleep(10);

        //进入临界区
        Monitor.Enter(obj);

        Console.WriteLine("当前数字:{0}", ++count);

        //退出临界区
        Monitor.Exit(obj);
    }
}

Monitor.Wait 和Monitor.Pulse

Wait:暂时释放资源锁,该线程进入“等待队列”中。

Pulse:唤醒“等待队列”中的线程,被唤醒的线程(被wait的)重新获得资源。

 

二、ReaderWriterLock类

      Monitor类实现的是资源在读写两种情况的临界区中只可以让一个线程访问,ReaderWriterLock类实现“写入串行,读取并行”。

<1>  AcquireWriterLock: 获取写入锁。

          ReleaseWriterLock:释放写入锁。

<2>  AcquireReaderLock: 获取读锁。

          ReleaseReaderLock:释放读锁。

<3>  UpgradeToWriterLock:将读锁转为写锁。

         DowngradeFromWriterLock:将写锁还原为读锁。

写法如下:

namespace Test
{
    class Program
    {
        static List<int> list = new List<int>();

        static ReaderWriterLock rw = new System.Threading.ReaderWriterLock();

        static void Main(string[] args)
        {
            Thread t1 = new Thread(AutoAddFunc);

            Thread t2 = new Thread(AutoReadFunc);

            t1.Start();

            t2.Start();

            Console.Read();
        }

        /// <summary>
/// 模拟3s插入一次
/// </summary>
/// <param name="num"></param>
        public static void AutoAddFunc()
        {
            //3000ms插入一次
            Timer timer1 = new Timer(new TimerCallback(Add), null, 0, 3000);
        }

        public static void AutoReadFunc()
        {
            //1000ms自动读取一次
            Timer timer1 = new Timer(new TimerCallback(Read), null, 0, 1000);
            Timer timer2 = new Timer(new TimerCallback(Read), null, 0, 1000);
            Timer timer3 = new Timer(new TimerCallback(Read), null, 0, 1000);
        }

        public static void Add(object obj)
        {
            var num = new Random().Next(0, 1000);

            //写锁
            rw.AcquireWriterLock(TimeSpan.FromSeconds(30));

            list.Add(num);

            Console.WriteLine("我是线程{0},我插入的数据是{1}。", Thread.CurrentThread.ManagedThreadId, num);

            //释放锁
            rw.ReleaseWriterLock();
        }

        public static void Read(object obj)
        {
            //读锁
            rw.AcquireReaderLock(TimeSpan.FromSeconds(30));

            Console.WriteLine("我是线程{0},我读取的集合为:{1}",
                              Thread.CurrentThread.ManagedThreadId, string.Join(",", list));
            //释放锁
            rw.ReleaseReaderLock();
        }
    }
}

 

posted @ 2016-08-25 11:19  xubenhua  阅读(167)  评论(0编辑  收藏  举报