Сегодня на собеседовании задал кандидату вопрос о том, как реализовать Singleton в C#. Сначала он предложил самый простой вариант (не thread safe) и в ходе дальнейшего обсуждения (“а почему так? а что если у нас многопоточное приложение? и что делать в этом случае?” и т.п.) предлагается вариант с блокировкой (внимание):
…
lock(typeof(MySingleton)) { …
В этот момент я подумал: “однако…”. На вопрос: “А почему так?” кандидат ответить затруднился, сославшись на некую статью, читаную им когда-то на просторах интернета.
На первый взгляд идея выглядит подкупающе свеж: не нужно держать отдельный объект, по которому идет синхронизация, все просто и элегантно. Даже MSDN подтверждает, что объекты класса Type уникальны (т.е. в своем роде синглтоны):
A Type object that represents a type is unique; that is, two Type object references refer to the same object if and only if they represent the same type.
Там же сказано, что объекты этого класса являются безопасными с точки зрения многопоточного доступа – ну прямо идеальный кандидат для наших нужд. Но мысль о том, почему же я никогда раньше не слышал о таком варианте, так и не давала покоя. Ответ содержится в той же самой статье:
Note:
In multithreading scenarios, do not lock Type objects in order to synchronize access to static data. Other code, over which you have no control, might also lock your class type. This might result in a deadlock. Instead, synchronize access to static data by locking a private static object.
Так что “увы и ах” - не судьба (даром что выглядит элегантно). И не забываем о пользе чтения документации.
HTH,
AlexS