当前位置:  开发笔记 > 编程语言 > 正文

静态属性和锁定用法

如何解决《静态属性和锁定用法》经验,为你挑选了1个好方法。

这段代码是正确的还是有任何随机线程死锁的可能性等?

使用静态属性并锁定在一起是一个好主意吗?或者是静态属性线程安全吗?

Private Shared _CompiledRegExes As List(Of Regex)
Private Shared Regexes() As String = {"test1.Regex", "test2.Regex"}
Private Shared RegExSetupLock As New Object

Private Shared ReadOnly Property CompiledRegExes() As List(Of Regex)
    Get
        If _CompiledRegExes Is Nothing Then
        SyncLock RegExSetupLock

            If _CompiledRegExes Is Nothing Then
                _CompiledRegExes = New List(Of Regex)(Regexes.Length - 1)

                For Each exp As String In Parser.Regexes
                    _CompiledRegExes.Add(New Regex(exp, RegexOptions.Compiled Or RegexOptions.CultureInvariant Or RegexOptions.IgnoreCase))
                Next

            End If

        End SyncLock

    End If

    Return _CompiledRegExes

End Get
End Property

如果不明显代码正在编译正则表达式并存储在List(Of Regex)中,那么它们可以更快地运行.并且它是共享的,因此每个类的实例都可以从中获益.



1> Jon Skeet..:

您的代码不是线程安全的,因为您使用双重检查锁定而不使字段变为volatile.不幸的是VB.NET没有volatile修饰符,所以你不能应用正常的修复.只需每次获取锁,或者在初始化类型时使用静态初始化初始化_CompiledRegExes.

请参阅我的单页为这至于单身了一般性讨论-我知道这是不是相当一个单,但已经很接近了.该页面提供了C#代码,但它应该很容易理解.

另外,我通常建议将锁变量设置为只读.你真的不想改变价值:)

笼统:

不,静态属性不是自动线程安全的

是的,可以锁定一个静态变量(但是显式地初始化它,就像你正在做的那样)

除非你真的知道自己在做什么,否则不要尝试编写无锁或低锁代码.我认为自己对线程知之甚少,我仍然不尝试使用双重检查锁等.

类型初始化是线程安全的(有几个注意事项,如果您有复杂的初始化它结了引用对方)所以这是做初始化这样一个好时机-那么你真的没有需要的锁.

编辑:您不需要将类型设为单例.只需编写函数来初始化列表并将其返回,然后在初始化器中为变量使用该函数:

' This has to be declared *before* _CompiledRegExes '
' as the initializer will execute in textual order '
' Alternatively, just create the array inside BuildRegExes '
' and don't have it as a field at all. Unless you need the array '
' elsewhere, that would be a better idea. '
Private Shared ReadOnly Regexes() As String = {"test1.Regex", "test2.Regex"}

Private Shared ReadOnly _CompiledRegExes As List(Of Regex) = BuildRegExes()

Private Shared ReadOnly Property CompiledRegExes() As List(Of Regex)
    Get
        Return _CompiledRegExes
    End Get
End Property

Private Shared Function BuildRegExes() As List(Of Regex)
    Dim list = New List(Of Regex)(Regexes.Length - 1)

    For Each exp As String In Regexes
        _CompiledRegExes.Add(New Regex(exp, RegexOptions.Compiled Or RegexOptions.CultureInvariant Or RegexOptions.IgnoreCase))
    Next
    Return list
End Function

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有