Ваш код не является потокобезопасным, поскольку вы используете двойную проверку блокировки, не делая поле нестабильным. К сожалению, в 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