oha*_*nho 3 .net c# multithreading
我有以下代码,其中"_ht"是表示缓存的Hashtable,"_ isLoaded"表示它是否已加载.
我们的系统有许多进程访问"_ht"对象,我需要它们等待它没有加载.
使用"_ht"作为锁定对象是错误的吗?我应该为此方案使用专用的对象类型类成员吗?
重要的是要提到这个班级是SINGLETON.
private Hashtable _ht = new Hashtable();
private bool _isLoaded = false;
internal Hashtable GetHT()
{
if (_isLoaded == false)
{
lock (_ht)
{
if (_isLoaded == false)
{
LoadHt(_ht);
}
}
}
return _ht;
}
Run Code Online (Sandbox Code Playgroud)
Pet*_*iho 10
您当然可以锁定Hashtable对象,就像您可以在lock语句中使用.NET中的任何引用类型实例一样.但是,它通常被认为是一种较差的方法,主要是因为当一个或多个锁定对象可用于代码的其他部分时,很难跟踪代码如何使用锁定,他们也可能将其用于锁定(再次,不可思议,但你会惊讶于人们有时写的代码).
通常,对于锁定,优选单独的锁定对象.我会注意到在你的代码示例中,_ht应该是readonly,如果你添加一个单独的锁定对象(例如lockObj),那也应该是readonly.
也就是说,单身场景不应该以这种方式实现.相反,您应该使用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;
}
Run Code Online (Sandbox Code Playgroud)
要么:
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;
}
Run Code Online (Sandbox Code Playgroud)
当你有可能被访问的类型的其他成员时,后者很有用,但是你想确保哈希表的初始化尽可能延迟(例如,如果可能没有代码实际访问它,那么你可以避免完全初始化它).
(我改变了所有内容,static因为你将你的场景描述为一个单例,在这种情况下,只有static成员对代码示例有意义).
最后我会注意到这Hashtable堂课非常过时了.作为一个非泛型类,您真的应该认真考虑升级代码以使用现在已经十年的泛型类型.该Dictionary<TKey, TValue>班是最直接的替代品,但人们有时用Hashtable一个简单的设置,为此,HashSet<T>数据结构会更合适.
| 归档时间: |
|
| 查看次数: |
319 次 |
| 最近记录: |