C# Lock 关键字

我们都知道,lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。也就是,说在多线程中,使用lock关键字,可以让被lock的对象,一次只被一个线程使用。

lock语句根本使用的就是Monitor.Enter和Monitor.Exit,也就是说lock(this)时执行Monitor.Enter(this),大括号结束时执行Monitor.Exit(this). 也就是说,Lock关键字,就是一个语法糖而已。

使用lock需要注意的地方:
1.lock不能锁定空值某一对象可以指向Null,但Null是不需要被释放的。(请参考:认识全面的null)
2.lock不能锁定string类型,虽然它也是引用类型的。因为字符串类型被CLR“暂留”
3.lock锁定的对象是一个程序块的内存边界
4.值类型不能被lock,因为前文标红字的“对象被释放”,值类型不是引用类型的
5.lock就避免锁定public 类型或不受程序控制的对象。

实例:
我们先看下加上lock和不加lock同一个程序有什么不同。


2789632-19cd8b9e7e00bf50.gif
不加lock

2789632-50f45f482ef01425.gif
使用lock

2789632-428b526350576852.gif
使用Monitor

Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LockDemo
{
    
    class Program
    {
        private static Student s1 = new Student() { name = "Tim", age = 8 };
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Task.Run(() => UpdateAge());
            }

            Console.ReadLine();
        }

        private static void UpdateAge()
        {
            lock (s1)
            {
                s1.age--;
                if (s1.age > 0)
                    Console.WriteLine($"s1.name:{s1.name}, s1.age: {s1.age}");
            }

        }
    }
    public class Student
    {
        public int age { get; set; }

        public string name { get; set; }
    }
}

所以在使用多线程的同时,这个时候使用lock就会对使用多线程的效率产生影响。之所以会有lock的产生,是由于对于公共的变量,为了避免多线程处理造成非预期的影响,对该对象进行上锁处理,确保该对象是我想要的那一个。
例如上述代码中的UpdateAge函数,输出的Console.WriteLine里面的是
就未必是s1.age--的s1,而可能是由于多线程,再次调用了UpdateAge()函数,此时刚好执行了s1.age--, 所以第一次的Console.WriteLine($"s1.name:{s1.name}, s1.age: {s1.age}"); 里面的age就存在很大的不确定性。

参考地址:https://www.cnblogs.com/ldyblogs/p/lock.html
https://www.cnblogs.com/lgxlsm/p/4834755.html

2789632-efebf88ad43e6aa3.png
张中华公众号
2789632-5c1e6ad6541eb996.jpg
张中华微信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值