欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#的Lock

程序员文章站 2022-04-15 10:49:07
有时候在编写线程并发的时候需要考虑异步和同步的问题。有些资源只能是一个线程访问,其他的线程在这个线程没有释放资源前不能访问。类似于操作系统中临界资源的访问。C#Lock包裹的代码块具有原子操作的特性(要么执行到结束为止,要么不执行)。 举个列子:银行账户的余额就是典型的临界资源的问题,假如原本有10 ......

有时候在编写线程并发的时候需要考虑异步和同步的问题。有些资源只能是一个线程访问,其他的线程在这个线程没有释放资源前不能访问。类似于操作系统中临界资源的访问。c#lock包裹的代码块具有原子操作的特性(要么执行到结束为止,要么不执行)。

举个列子:银行账户的余额就是典型的临界资源的问题,假如原本有1000,你的情妇a,b先后打500给你。a打500的这个操作是一个线程,从数据库取出余额的值累加正准备写回数据库的时候,由于某种原因(时间片用完、来了更高的优先级的线程)阻塞,这时候b又给你打500,他得到余额依然是1000,累加后写回数据库1500到手。这时刚才被阻塞的线程又获得执行权,将1500写回数据库。你莫名奇妙少了500,回去找情妇理论是没有结果的,银行系统的锅。

lock可以运用在单列模式上。刚开始我一直纳闷lock括号里面究竟写什么,经同学指点。大概是任意不会改变的对象(里面写一个固定的字符串”999“也可以)

那个对象是一把锁。它会把钥匙给第一个访问它的进程,如果进程完事就上交钥匙。有且只有一把钥匙,实现了原子操作

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;

namespace testlock
{
    class testthread
    {
        private static testthread instance;
        private static object obj = new object();
        private testthread() { }

        public static void getinstance()
        {
            if (instance == null)//先判断,异步
            {
               lock (obj)//任意不改变对象
                {
                    if (instance == null)//同步
                    {
                        console.writeline("初始化");
                        instance = new testthread();
                    }
                }
             }
         }
    }
}

  

thread t1 = new thread(testthread.getinstance);
thread t2 = new thread(testthread.getinstance);
thread t3 = new thread(testthread.getinstance);
t1.start();
t2.start();
t3.start();

  结果是只打印一行初始化,如果没有lock包裹那块代码那么结果会有三行初始化。因为,线程都会遇到if (instance == null)真