Asp.net 试图了解SyncLock是如何工作的
我做了两个静态类的测试Asp.net 试图了解SyncLock是如何工作的,asp.net,vb.net,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 In
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
它可以工作
这是我用synclock锁定的两个不同的对象,但它对它们的处理是相同的。这是为什么?SyncLock语句将对象引用作为其参数。由于
字符串
类型是引用类型,因此您的代码满足该约束。但是,由于在.Net中,两个单独的字符串
引用的文本值相等也导致了gObject2.TestSyncLock
和gObject3.TestSyncLock
之间的引用相等
发件人:(重点加上)
公共语言运行库自动维护一个名为
实习生池,其中包含每个唯一用户的单个实例
程序中声明的文本字符串常量,以及任何唯一
通过调用Intern以编程方式添加的字符串的实例
方法
实习生池保存字符串存储如果指定了文字
字符串常量设置为多个变量,每个变量都设置为
在实习生池中引用相同的常量,而不是引用
具有相同值的多个不同字符串实例。
由于gObject2.TestSyncLock
和gObject3.TestSyncLock
都指向相同的String
引用,SyncLock gObject2.TestSyncLock
将阻止SyncLock gObject3.TestSyncLock
主题代码是一个很好的例子,说明了字符串插入如何导致意外行为。这篇文章提供了有关实习机制的更多细节,还提供了实习可能导致意外结果的另一个例子
因此,这个故事的寓意是避免使用字符串作为SyncLock
的参数。使用类似以下内容更安全:
NotInheritable Class gObject2
Public Shared TestSyncLock As New Object
End Class
NotInheritable Class gObject3
Public Shared TestSyncLock As New Object
End Class
如果将其中一个字符串更改为
test123
,会发生什么情况?也许SyncLock
做的是正常的比较,而不是参考比较?@visualincent我认为你的建议完全没有根据,但是当我将字符串从test
更改为test123
时,它工作了。大概它在幕后使用了Object.Equals
,这将测试类型string
的值相等性。我建议专门为锁定而创建的对象应该是typeObject
。如果它们的存在仅仅是为了锁定,那么它们就不应该有任何数据,因为这些数据可能没有任何有用的用途。正如jmchilinney所说,建议使用System.Object
来同步锁定。它只能通过其引用进行比较,因此两个同步锁必须使用完全相同的对象实例才能阻止其中一个。@VisualIncent和Henry,两个类之间字符串引用相等的可能原因是字符串“test”被CLR池占用。见: