我制作了两个静态类
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
it works
到目前为止一切都很好。
现在当我去synclock1.apx然后在另一个浏览器中访问synclock2.aspx时,synclock2.aspx在synclock1.aspx完成之前没有完成加载。
这是我用synclock锁定的两个不同的对象,但它对它们的处理方式相同。这是为什么?
答案 0 :(得分:3)
SyncLock
语句将对象引用作为其参数。由于String
类型是引用类型,因此您的代码满足该约束。但是,由于.Net中的String Interning,两个单独的String
引用的字面值相等也导致gObject2.TestSyncLock
和gObject3.TestSyncLock
之间的引用相等。
来自:String.IsInterned Method - Remarks(强调补充)
公共语言运行库自动维护一个名为的表 实习池,包含每个唯一的单个实例 在程序中声明的文字字符串常量,以及任何唯一的 通过调用Intern以编程方式添加的String实例 方法
实习池保存了字符串存储空间。 如果您指定文字 字符串常量为几个变量,每个变量都设置为 在实习池中引用相同的常量而不是引用 具有相同值的几个不同的String实例。
由于gObject2.TestSyncLock
和gObject3.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