C#多线程编程中的锁系统基本用法

前端技术 2023/09/04 C#

平常在多线程开发中,总避免不了线程同步。本篇就对net多线程中的锁系统做个简单描述。

目录
一:lock、Monitor
     1:基础。
     2: 作用域。
     3:字符串锁。
     4:monitor使用
二:mutex
三:Semaphore
四:总结

一:lock、Monitor

1:基础

Lock是Monitor语法糖简化写法。Lock在IL会生成Monitor。

复制代码 代码如下:

//======Example 1=====
            string obj = \"helloworld\";
            lock (obj)
            {
                Console.WriteLine(obj);
            }
            //lock  IL会编译成如下写法
            bool isGetLock = false;
            Monitor.Enter(obj, ref isGetLock);
            try
            {
                Console.WriteLine(obj);
            }
            finally
            {
                if (isGetLock)
                {
                    Monitor.Exit(obj);
                }
            }

isGetLock参数是Framework  4.0后新加的。 为了使程序在所有情况下都能够确定,是否有必要释放锁。例: Monitor.Enter拿不到锁

Monitor.Enter 是可以锁值类型的。锁时会装箱成新对象,所以无法做到线程同步。

2:作用域

     一:Lock是只能在进程内锁,不能跨进程。走的是混合构造,先自旋再转成内核构造。

     二:关于对type类型的锁。如下:

复制代码 代码如下:

//======Example 2=====
            new Thread(new ThreadStart(() => {
                lock (typeof(int))
                {
                    Thread.Sleep(10000);
                    Console.WriteLine(\"Thread1释放\");
                }
            })).Start();
            Thread.Sleep(1000);
            lock(typeof(int))
            {
                Console.WriteLine(\"Thread2释放\");
            }

运行结果如下:

我们在来看个例子。

复制代码 代码如下:

//======Example 3=====
            Console.WriteLine(DateTime.Now);
            AppDomain appDomain1 = AppDomain.CreateDomain(\"AppDomain1\");
            LockTest Worker1 = (LockTest)appDomain1.CreateInstanceAndUnwrap(
             Assembly.GetExecutingAssembly().FullName,
             \"ConsoleApplication1.LockTest\");
            Worker1.Run();

            AppDomain appDomain2 = AppDomain.CreateDomain(\"AppDomain2\");
            LockTest Worker2 = (LockTest)appDomain2.CreateInstanceAndUnwrap(
            Assembly.GetExecutingAssembly().FullName,
            \"ConsoleApplication1.LockTest\");
            Worker2.Run();
/// <summary>
    /// 跨应用程序域边界或远程访问时需要继承MarshalByRefObject
    /// </summary>
    public class LockTest : MarshalByRefObject
    {
        public void Run()
        {
            lock (typeof(int))
            {
                Thread.Sleep(10000);
                Console.WriteLine(AppDomain.CurrentDomain.FriendlyName + \": Thread 释放,\" + DateTime.Now);
            }
        }
    }

本文地址:https://www.stayed.cn/item/10617

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。