C# .Net锁(上下文)是原子的吗?

C# .Net锁(上下文)是原子的吗?,c#,thread-safety,locking,atomicity,C#,Thread Safety,Locking,Atomicity,我知道.net锁确保只有一个线程执行锁范围内的代码行 我不明白的是锁是否是原子的。 执行锁定代码时线程是否可以中断 例如,在我看来,如果锁不是原子的,那么以下代码就不是线程安全的: Class example { private int myNumber; private object context = new object(); void Write() { myNumber--; } void WriteLock() { lock (context)

我知道.net锁确保只有一个线程执行锁范围内的代码行

我不明白的是锁是否是原子的。 执行锁定代码时线程是否可以中断

例如,在我看来,如果锁不是原子的,那么以下代码就不是线程安全的:

Class example
{
  private int myNumber;
  private object context = new object();

 void Write()
 {
    myNumber--;
 }

 void WriteLock()
 {
     lock (context)
     {
        myNumber++;
        print(myNumber);
     }
 }
}


如果线程A形成方法WriteLock(),并且由于线程B正在执行Write()而被中断,则myNumber可能会被不安全地更改。我说的对吗?

检查msdn文档。我可以想象,它要么是原子的,要么正在实现某种其他模式,以确保这不会发生

示例中的问题是,Write方法还应该在递减myNumber之前获得锁,这样其他线程就不能更改共享资源

void Write()
{
  lock(context) {
    myNumber--;
  }
}

查看msdn文档。我可以想象,它要么是原子的,要么正在实现某种其他模式,以确保这不会发生

示例中的问题是,Write方法还应该在递减myNumber之前获得锁,这样其他线程就不能更改共享资源

void Write()
{
  lock(context) {
    myNumber--;
  }
}

查看msdn文档。我可以想象,它要么是原子的,要么正在实现某种其他模式,以确保这不会发生

示例中的问题是,Write方法还应该在递减myNumber之前获得锁,这样其他线程就不能更改共享资源

void Write()
{
  lock(context) {
    myNumber--;
  }
}

查看msdn文档。我可以想象,它要么是原子的,要么正在实现某种其他模式,以确保这不会发生

示例中的问题是,Write方法还应该在递减myNumber之前获得锁,这样其他线程就不能更改共享资源

void Write()
{
  lock(context) {
    myNumber--;
  }
}

不,那是像虫子一样大声叫。这些操作符不是原子的,尽管它们看起来像原子。在引擎盖下,它们作为读修改写操作,三个操作而不是一个。因此,它们本身不是原子的。Write()中缺少的锁允许它与WriteLock()并发执行。结果是任意的,包括当Write在WriteLock之前运行时没有任何更改,并且当WriteLock在Write之前运行时,该值实际上会减小

线程拥有锁时被中断并不重要,锁只会保持更长时间


使用Interlocked.Increment()和Decrement()来获得一个更便宜的版本,它不需要锁。

不,这就像一个bug一样大声叫喊。这些操作符不是原子的,尽管它们看起来像原子。在引擎盖下,它们作为读修改写操作,三个操作而不是一个。因此,它们本身不是原子的。Write()中缺少的锁允许它与WriteLock()并发执行。结果是任意的,包括当Write在WriteLock之前运行时没有任何更改,并且当WriteLock在Write之前运行时,该值实际上会减小

线程拥有锁时被中断并不重要,锁只会保持更长时间


使用Interlocked.Increment()和Decrement()来获得一个更便宜的版本,它不需要锁。

不,这就像一个bug一样大声叫喊。这些操作符不是原子的,尽管它们看起来像原子。在引擎盖下,它们作为读修改写操作,三个操作而不是一个。因此,它们本身不是原子的。Write()中缺少的锁允许它与WriteLock()并发执行。结果是任意的,包括当Write在WriteLock之前运行时没有任何更改,并且当WriteLock在Write之前运行时,该值实际上会减小

线程拥有锁时被中断并不重要,锁只会保持更长时间


使用Interlocked.Increment()和Decrement()来获得一个更便宜的版本,它不需要锁。

不,这就像一个bug一样大声叫喊。这些操作符不是原子的,尽管它们看起来像原子。在引擎盖下,它们作为读修改写操作,三个操作而不是一个。因此,它们本身不是原子的。Write()中缺少的锁允许它与WriteLock()并发执行。结果是任意的,包括当Write在WriteLock之前运行时没有任何更改,并且当WriteLock在Write之前运行时,该值实际上会减小

线程拥有锁时被中断并不重要,锁只会保持更长时间


使用Interlocked.Increment()和Decrement()可以获得不需要锁的更便宜版本。

为什么不在多线程环境中试用?为什么不在多线程环境中试用?为什么不在多线程环境中试用?为什么不在多线程环境中试用?嘿,Dave。我不认为额外的锁解决了我的问题。如果执行此锁的代码时线程被中断怎么办?您必须在更改任何共享资源之前获得一个锁。因为在递减myNumber之前您没有获得上下文对象上的锁,所以您允许其他线程有机会递减myNumber,而您示例中的线程a处于临界部分。锁只阻止线程访问该代码段,而不是通常的共享资源。戴夫-关于你提到的附加锁,你是对的,我刚刚花了一些时间来理解你的观点。谢谢你的回答:)嘿,戴夫。我不认为额外的锁解决了我的问题。如果执行此锁的代码时线程被中断怎么办?您必须在更改任何共享资源之前获得一个锁。因为在递减myNumber之前您没有获得上下文对象上的锁,所以您允许其他线程有机会递减myNumber,而您示例中的线程a处于临界部分。锁只阻止线程访问该代码段,而不是通常的共享资源。戴夫-关于你的额外锁,你是对的