을 지적 @PeterDuniho. 그러나 일반적으로 하나의 잠금 객체가 코드의 다른 부분에서 사용할 수있을 때 코드가 잠금을 사용하는 방식을 추적하는 것이 어렵 기 때문에 열등한 접근 방식으로 간주됩니다 (잠금을 위해 잠금 객체를 사용할 수도 있습니다). 다시 말하지만, 사람들이 때때로 쓰는 코드에 놀랄 것입니다.)
일반적으로 잠금의 경우 별도의 잠금 개체가 바람직합니다. 코드 예에서 _ht
은 readonly
이어야하며 별도의 잠금 객체 (예 : lockObj
)를 추가하면 읽기 전용이어야합니다.
그렇다고 싱글 톤 시나리오를 이런 방식으로 구현하면 안됩니다.
private static readonly Hashtable _ht = InitializeTable();
internal static Hashtable GetHT() { return _ht; }
private static Hashtable InitializeTable()
{
Hashtable table = new Hashtable();
LoadHt(table);
return table;
}
또는 : 대신, 당신은 CLR 자신의 정적 초기화, 또는 Lazy<T>
클래스를 사용해야 하나
private static readonly Lazy<Hashtable> _ht = new Lazy<Hashtable>(() => InitializeTable());
internal static Hashtable GetHT() { return _ht.Value; }
private static Hashtable InitializeTable()
{
Hashtable table = new Hashtable();
LoadHt(table);
return table;
}
당신이 액세스 할 수있는 유형의 다른 구성원이있을 때 후자가 유용합니다, 하지만 가능한 한 오랫동안 해시 테이블 초기화가 지연되도록해야합니다 (예 : 실제로 코드에 액세스 할 수없는 경우이를 초기화하지 않아도 됨).
(나는 시나리오를 싱글 톤으로 설명했기 때문에 모든 것을 static
으로 변경했으며이 경우 코드 예제에서는 static
구성원 만 이해할 수 있음).
마지막으로 Hashtable
클래스의 기한이 오래되었습니다. 비 제네릭 클래스로서, 당신은 정말로 코드를 10 년 된 제네릭 타입을 사용하도록 업그레이드하는 것을 진지하게 고려해야합니다. Dictionary<TKey, TValue>
클래스가 가장 직접적인 대체 클래스이지만 사람들은 간략한 집합으로 Hashtable
을 사용하기 때문에 HashSet<T>
데이터 구조가 더 적절할 수 있습니다.
잠금 개체를 사용하는 이유에 관해서는 내 대답을 사용하기를 원한다면, 꽤 분명하다고 생각합니다. 그렇지 않다면 생각해야합니다. 어쨌든 너는 –
@ohadinho를 알고있다. 왜냐하면 _usually_ 별도의'object'가 사용되지만 당신이 잠그고있는 객체가'Hashtable'을 직접 사용하는 것은 잘못된 것보다'private' 일 때까지입니다. 클래스와 그 밖에 아무도 그 객체에 대해 잠글 수있는 객체의 가시성을 갖지 않으므로 죽은 자물쇠의 소스가 아닙니다. 그 말은 **이 코드 **를 모두 삭제하고'Lazy '을 사용하는 것입니다. –
@AdrianoRepetti : _field_가 'private'로 선언 되었기 때문에 개체 자체가 비공개임을 의미하지는 않습니다. 그리고 실제로,이 예제에서'Hashtable' 객체는'GetHT()'메소드를 통해 ('internal'이지만 내부 클래스이지만 여전히) 공개됩니다. –