你當然可以鎖定Hashtable
對象,就像你可以在lock
語句中使用任何引用類型實例的.NET。然而,它通常被認爲是一種劣質的方法,主要是因爲當代碼的其他部分有一個或多個鎖對象可用時,他們很難跟蹤代碼如何使用鎖定,他們也可能使用它來鎖定再次,不可思議,但你會驚訝於人們寫的代碼)。
對於通常的鎖定,單獨的鎖定對象是最好的。我會注意到在你的代碼示例中,_ht
應該是readonly
,並且如果你添加一個單獨的鎖定對象(例如lockObj
),它也應該是隻讀的。
也就是說,單例情景不應該以這種方式實現。相反,您應該使用CLR自己的靜態初始化,或Lazy<T>
類:
private static readonly Hashtable _ht = InitializeTable();
internal static Hashtable GetHT() { return _ht; }
private static Hashtable InitializeTable()
{
Hashtable table = new Hashtable();
LoadHt(table);
return table;
}
或者:
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
這個類已經過時了。作爲非泛型類,您應該認真考慮升級代碼以使用現在十年的泛型類型。 Dictionary<TKey, TValue>
類是最直接的替代品,但人們有時使用Hashtable
作爲一個簡單集合,對此,數據結構更合適。
如果你想讓我花費我的答案,爲什麼要使用鎖對象說,所以我認爲這是非常明顯的,如果不是,那麼你應該考慮它。反正lemme知道 – 2014-11-23 08:37:47
@ohadinho很多人說_usually_使用了一個單獨的'object',但直到你鎖定的對象是'private',而不是直接使用你的'Hashtable'沒有任何錯誤(記住你正在鎖定一個實例,而不是一個類,而且沒有其他人知道該對象鎖定它,所以它不是死鎖的來源)。這就是說我會**這個代碼全部放在一起,我會用'懶惰'。 –
2014-11-23 08:44:08
@AdrianoRepetti:請注意,僅僅因爲_field_被聲明爲「private」,並不意味着該對象本身是私有的。實際上,在這個例子中,'Hashtable'對象實際上是通過'GetHT()'方法公開的(儘管只是'內部',但仍然在擁有類之外)。 – 2014-11-23 08:50:57