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();
            }
        }
    }
  • 相关阅读:
    linux umask使用详解
    Linux 解压压缩命令
    linux命令:tail 命令
    linux命令:head 命令
    linux下cat命令详解
    linux命令:rm 命令
    linux命令:mv命令
    Linux 的cp命令
    文件权限详解
    Linux ls命令参数详解
  • 原文地址:https://www.cnblogs.com/benhua/p/5806037.html
Copyright © 2011-2022 走看看