c# – 是否可以使用Hashtable作为锁定对象?
我有以下代码,其中“_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; } 解决方法
您当然可以锁定Hashtable对象,就像在lock语句中使用.NET中的任何引用类型实例一样.但是,它通常被认为是一种较差的方法,主要是因为当一个或多个锁定对象可用于代码的其他部分时,很难跟踪代码如何使用锁定,他们也可能将其用于锁定(再次,不可思议,但你会惊讶于人们有时写的代码).
通常,对于锁定,优选单独的锁定对象.我会注意到在你的代码示例中,_ht应该是只读的,如果你添加一个单独的锁定对象(例如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; } 要么: 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; } 当你有可能被访问的类型的其他成员时,后者很有用,但是你想确保哈希表的初始化尽可能延迟(例如,如果可能没有代码实际访问它,那么你可以避免完全初始化它). (我将所有内容都更改为静态,因为您将场景描述为单例,在这种情况下,只有静态成员才能对代码示例有意义). 最后我会注意到Hashtable类非常过时.作为一个非泛型类,您真的应该认真考虑升级代码以使用现在已经十年的泛型类型.字典< TKey,TValue> class是最直接的替换,但人们有时使用Hashtable作为简单集合,其中HashSet< T>数据结构会更合适. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |