试图了解SyncLock的工作原理

时间:2017-04-09 21:49:13

标签: asp.net vb.net

我制作了两个静态类

NotInheritable Class gObject2
    Public Shared TestSyncLock As String = "test"
End Class

NotInheritable Class gObject3
    Public Shared TestSyncLock As String = "test"
End Class

然后我有两个aspx

Synclock1.aspx:

Public Class SyncLock1
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        SyncLock gObject2.TestSyncLock
            Thread.Sleep(10000)
        End SyncLock
    End Sub

End Class

Synclock2.aspx

Public Class SyncLock2
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        SyncLock gObject3.TestSyncLock
            SomeDiv.InnerHtml = "It works"
        End SyncLock
    End Sub
End Class
  1. 当我转到synclock1.aspx时,它会旋转10秒并按预期显示空白页面。
  2. 当我去synclock2.aspx时,它会吐出it works
  3. 到目前为止一切都很好。

    现在当我去synclock1.apx然后在另一个浏览器中访问synclock2.aspx时,synclock2.aspx在synclock1.aspx完成之前没有完成加载。

    这是我用synclock锁定的两个不同的对象,但它对它们的处理方式相同。这是为什么?

1 个答案:

答案 0 :(得分:3)

SyncLock语句将对象引用作为其参数。由于String类型是引用类型,因此您的代码满足该约束。但是,由于.Net中的String Interning,两个单独的String引用的字面值相等也导致gObject2.TestSyncLockgObject3.TestSyncLock之间的引用相等。

来自:String.IsInterned Method - Remarks(强调补充)

  

公共语言运行库自动维护一个名为的表   实习池,包含每个唯一的单个实例   在程序中声明的文字字符串常量,以及任何唯一的   通过调用Intern以编程方式添加的String实例   方法

     

实习池保存了字符串存储空间。 如果您指定文字   字符串常量为几个变量,每个变量都设置为   在实习池中引用相同的常量而不是引用   具有相同值的几个不同的String实例。

由于gObject2.TestSyncLockgObject3.TestSyncLock都指向相同的String引用,SyncLock gObject2.TestSyncLock会阻止SyncLock gObject3.TestSyncLock

主题代码是字符串实习如何导致意外行为的一个很好的例子。文章Interning Strings and immutability提供了有关实习机制的更多详细信息,并提供了另一个实习可能导致意外结果的示例。

因此,这个故事的寓意是避免使用字符串作为SyncLock的论据。使用类似以下内容更安全:

NotInheritable Class gObject2
     Public Shared TestSyncLock As New Object
End Class

NotInheritable Class gObject3
     Public Shared TestSyncLock As New Object
End Class