lock

本文详细介绍了C#中lock关键字的使用方法及注意事项,包括如何正确地选择锁定对象以实现线程间的同步,避免死锁及竞态条件等问题。同时强调了最佳实践,如定义私有静态对象进行锁定。

首先先上官方Msdn的说法:

  lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
  lock 关键字在块的开始处调用 Enter,而在块的结尾处调用 Exit。 ThreadInterruptedException 引发,如果 Interrupt 中断等待输入 lock 语句的线程。
  通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。

  常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
  如果实例可以被公共访问,将出现 lock (this) 问题。
  如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
  由于进程中使用同一字符串的任何其他代码都将共享同一个锁,所以出现 lock("myLock") 问题。
  最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。
  在 lock 语句的正文不能使用 等待 关键字。

lock 语句的表达式必须表示一个引用类型的值。永远不会为 lock 语句中的表达式执行隐式装箱转换,因此,如果该表达式表示的是一个值类型的值,则会导致一个编译时错误。

C#中引用类型主要有:数组、类、接口、委托、object、字符串,但是最好不要锁字符串;使用lock同步时,应保证lock的是同一个对象,而给字符串变量赋值并不是修改它,而是重新创建了新的对象,这样多个线程以及每个循环之间所lock的对象都不同,因此达不到同步的效果。常用做法是创建一个object对象,并且永不赋值。

private static object objlock = new object();

private
static object _staticObject; public static object StaticObject {  get { if(_staticObject==null)//判断为空 { lock(objlock)//加锁 { if(_staticObject==null)//再次判断             _staticObject=new object();//初始化 } }     return _staticObject; } }

 

转载于:https://www.cnblogs.com/tingqianzhu/p/8488894.html

09-02
C#中的lock关键字是多线程编程中重要的同步控制机制,通过Monitor类来避免数据竞争和并发问题,确保线程安全,以下是详细介绍: ### 使用方法 lock关键字通过锁定一个对象来工作,任何线程在尝试进入被lock保护的代码块之前,都必须先获得该对象的锁。如果一个线程已经获得了锁,其他线程就必须等待,直到锁被释放。当线程退出lock代码块时,无论是因为正常执行完毕还是由于异常退出,锁都会被自动释放。基本语法如下: ```csharp object lockObject = new object(); // 用于锁定的对象,通常是一个私有的、只读的字段 public void Method() { lock (lockObject) { // 访问或修改被保护的资源 // ... } } ``` 示例代码: ```csharp private readonly object _lockObject = new object(); public void IncrementCount() { lock (_lockObject) { // 模拟对共享资源的访问 _count++; // 假设 _count 是一个需要线程安全的字段 } } ``` ### 应用场景 在多线程环境中,当多个线程可能同时访问和修改共享资源时,使用lock关键字可以确保在同一时刻只有一个线程能够访问该资源,避免数据竞争和并发问题。例如多个线程同时对一个计数器进行递增操作,使用lock关键字可以保证计数器的值正确递增。 ### 注意事项 1. **锁对象的选择**:锁对象必须是引用类型,通常是一个私有的、只读的字段,以避免外部代码意外地锁定或解锁对象。 2. **避免死锁**:在复杂的多线程程序中,如果不当使用lock,可能会导致死锁(两个或多个线程相互等待对方释放锁)。设计时要特别注意锁的获取顺序。 3. **性能考虑**:虽然lock是解决多线程同步问题的有效手段,但它也会引入性能开销。频繁地锁定和解锁可能会降低程序的性能。 4. **异常处理**:即使lock代码块中发生了异常,锁也会自动释放,但应该确保异常处理逻辑能够正确处理lock代码块中可能发生的任何问题。 5. **避免锁定公共类型或string**:因为公共类型或字符串字面量可能被程序中的多个部分共享,这可能导致不期望的锁定行为。 6. **使用Monitor类**:lock关键字实际上是对System.Threading.Monitor类的封装。如果需要更细粒度的控制(如尝试获取锁而不阻塞线程),可以直接使用Monitor类。 [^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值