很少有关于锁的令人困惑的事情

Asp*_*Net 14 .net c# multithreading

我知道如何在我的应用程序中使用锁,但是我对锁定还不太了解(BTW - 我知道lock语句只是使用Monitor类类型的简写符号).

来自http://msdn.microsoft.com/en-us/library/ms173179.aspx:

 public class TestThreading
 {
     private System.Object lockThis = new System.Object();

     public void Function()
     {

         lock (lockThis)
         {
            // Access thread-sensitive resources.
         }
     }
  }
Run Code Online (Sandbox Code Playgroud)

提供给lock关键字的参数必须是基于引用类型的对象,并用于定义锁的范围.在上面的示例中,锁定范围仅限于此函数,因为在函数外部不存在对象lockThis的引用.如果确实存在这样的引用,则锁定范围将扩展到该对象.

a)我不明白lockThis对象如何定义锁的范围.锁的范围是锁(lockThis){和相邻}之间的所有代码,那么"锁定范围将扩展到该对象"究竟是什么意思?

b)术语锁定对象锁定 是什么意思?只是我们使用lockThis的引用来锁定代码区域?因此,该术语并不表示我们锁定了lockThis这个对象?

感谢名单


回复David Morton:

如果我的答复有点冗长,我道歉,但我想不出任何其他方式来表达我的问题,仍然有点连贯:

  1. 在这种情况下,锁的范围是类本身的单个实例.这与跨越特定类的所有实例相反.你可以通过使lockThis静态来锁定所有实例TestThreading.这就是锁的"范围"的含义:它是适用于单个实例,还是适用于特定类型的每个实例.

其他对象仍然可以从另一个线程访问lockThis,但是它们无法处理被该对象上的锁包围的代码.

如果我们调用由lock(位于TestThreading.Function内)C包围的代码,那么由于TestThreading.Function不是静态的,每个TestThreading实例都有自己的C副本.但是如果TestThreading.Function是静态的,那么所有TestThreading实例都将共享相同的C副本.作为类比,如果C是一个房间,如果TestThreading.Function不是静态的,那么每个TestThreading实例都有自己的C空间,但如果函数是静态的,那么所有TestThreading实例将共享相同的C空间.

按照这个类比,我将lockThis解释为C室的关键.如果lockThis是静态的,如果TestThreading.Function不是静态的,那么所有TestThreading情况下将使用相同的密钥输入自己Ç房间.

  • 因此,我看不出有任何意义lockThis是静态或没有,因为在任何情况下,每个TestThreading实例将使用lockThis进入自己的房C(假设TestThreading.Function不是静态).因此,遵循该逻辑,锁的范围不应该始终是类的单个实例(假设TestThreading.Function不是静态的)?

  • 同样的,我没有看到任何意义lockThis是私人或公共的,因为再次TestThreading实例将使用lockThis进入自己的房C(假设TestThreading.Function不是静态)


第二回复大卫莫顿

回应你的回答:有一个意义.如果TestThreading.Function是静态的,那么lockThis必须是静态的,否则,TestThreading.Function根本无法访问lockThis.

我不知道你是什么意思TestThreading.Function不能够访问lockThis?!再次假设我们调用由lock(位于TestThreading.Function内)C包围的代码.如果TestThreading.Function是静态的,因此只有一个房间,但lockThis是非静态的,如果我们有以下定义:

 public class TestThreading
 {
    private System.Object lockThis = new System.Object();

    public static  void Function()
    {

        lock (new TestThreading().lockThis)
        {
           // Access thread-sensitive resources.
        }
    }
 }
Run Code Online (Sandbox Code Playgroud)

,然后每当某个线程访问C室时,它就会使用一个新密钥.因此,如果100个线程访问C室,那么使用100个不同的密钥打开同一个房间?!所以代码确实有效,它没有多大意义,因为线程之间根本没有同步?!

在这种情况下,锁的范围是类本身的单个实例.这与跨越特定类的所有实例相反.你可以通过使lockThis静态来锁定所有实例TestThreading.

对锁的术语范围感到困惑,因为我把它解释为:如果lockThis是静态的,那么所有TestThread实例都会共享同一个房间(也就是锁),即使TestThread.Function不是静态的.假设我现在理解正确,那么术语锁是指用于打开门的钥匙(因此锁不是指房间?!)?

因此,如果我们假设lockThis是静态的,TestThread.Function也不是一成不变的,那么键/锁的范围是所有TestThread情况下,这意味着所有TestThread情况下,当一个共享同一个密钥,因此TestThread例如打开门使用此密钥到其房间,其他实例将无法打开他们的房间的门,直到第一个实例释放该密钥?


第三回复David Morton

不,如果Function是静态的,那么所有TestThread实例将共享同一个房间,如果lockThis是静态的,则所有TestThread实例将共享相同的密钥.

你是否同意锁定的句子范围中使用的单词至少在某种程度上是指键(键是lockThis实例)?

房间是在锁内执行的代码,而不是lockThis对象本身,这只是密钥.

[防御模式开启]这就是我在上次回复中所说的内容.;)[防御模式OFF]

Dav*_*ton 8

  1. 在这种情况下,锁的范围是类本身的单个实例.这与跨越特定类的所有实例相反.你可以通过使lockThis静态来锁定所有实例TestThreading.这就是锁的"范围"的含义:它是适用于单个实例,还是适用于特定类型的每个实例.

  2. "锁定对象thisObject"只是意味着使用thisObject作为确定我们是否在锁中的对象.该术语并不表示我们"锁定"了lockThis对象.我认为你的估计是正确的.其他对象仍然可以从另一个线程访问lockThis,但是它们无法处理被对象上的锁包围的代码.

由于我们互相回应,这里有更多信息:

让我们采取您在上面概述的"房间和钥匙"类比,并为每种可能性扩展它.我们有几种不同的情况:

  1. 静态函数,静态锁定对象 - 这类似于拥有一个房间,只有一个密钥.
  2. 实例函数,静态锁定对象 - 这就像拥有多个共享相同密钥的房间......例如,如主密钥.
  3. 实例函数,实例锁定对象 - 这就像有几个房间,每个房间都有自己的钥匙......就像宿舍或酒店一样.
  4. 静态函数,实例锁定对象 - 不可能.您无法从静态上下文访问实例字段.

希望上述方案概述了这些方案如何协同工作.

回应第二个回应

我不确定你的意思是TestThreading.Function无法访问lockThis?!

它无法访问有用的 lockThis.锁定在锁定完成时被抛弃的实例上的静态方法是无用的.在您设置的场景中,每次接近门时,锁定"放弃"一个新钥匙,并说"好吧,我接受我刚给你的钥匙......你可以进来".在那种情况下,它太松散地守护着"房间",让每个人都可以随时访问.换句话说,在第二个例子中没有理由甚至有一个锁定语句.这就像房间有一个动态增加的门数,只使用一次,其中有一个密钥贴在上面.无数人可以随时进入.你的代码和以下代码之间没有区别,真的(有,但是这样你可以希望得到这个概念:

public class TestThreading
{
    private object lockThis = new object();

    public static void Function() 
    {
        lockThis = new object();
        lock (lockThis)
        {
            // access something   
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在上面这个例子中所做的基本上是扔掉,然后在我在门上使用之前重新锁上锁.那没用.你是对的,没有任何线程同步,从这个意义上说,我会说代码根本不起作用,因为锁的整个点是同步线程.

如果lockThis是静态的,那么所有TestThread实例将共享同一个房间(也就是锁),即使TestThread.Function不是静态的.假设我现在理解正确,那么术语锁是指用于打开门的钥匙(因此锁不是指房间?!)?

不,如果Function是静态的,那么所有TestThread实例将共享同一个房间,如果lockThis是静态的,则所有TestThread实例将共享相同的密钥.

lock (key)
{
   // room
}
Run Code Online (Sandbox Code Playgroud)

房间是在锁内执行的代码,而不是lockThis对象本身,这只是密钥.

因此,如果我们假设lockThis是静态的并且TestThread.Function不是静态的,则键/锁的范围是所有TestThread实例,这意味着所有TestThread实例共享相同的键,因此当一个TestThread实例打开门时使用此密钥到其房间,其他实例将无法打开他们的房间的门,直到第一个实例释放该密钥?

是.