zoukankan      html  css  js  c++  java
  • 多线程的锁

    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();
            }
        }
    }
  • 相关阅读:
    第二次刷题感受——路漫漫其修远兮,吾将上下而求索。
    刷题就是照镜子——第一次刷2008年初赛题感受
    第一次集训刷题感受
    我的第一个博客
    预测房价的回归问题
    电影评论的情感极性分析
    语音助手是这样子的(二)
    语音助手是这样子的(一)
    软工第一次作业
    2020软件工程第五次作业_第二组
  • 原文地址:https://www.cnblogs.com/benhua/p/5806037.html
Copyright © 2011-2022 走看看