一个 .net hashtable 的锁的疑惑和解决 -尊龙游戏旗舰厅官网
今天同事告诉我, 锁 hashtable 应该锁它的 syncroot 属性而不应该锁它的实例, 例如:
hashtable ht = new hashtable();
lock(ht.syncroot)
{
...
}
看了 .net framework 文档, 给的例子也是锁 syncroot 属性, 说如果锁实例的话不能保证在并发情况下的同步, 我很疑惑, 为什么不能锁 hashtable 实例本身呢?
做了个实验, 两个线程 a 和 b, 用锁实例和锁 syncroot 两种方式测试, 都没有问题, 结果是一样的。
后来, 用 hashtable.synchronized 创建自动线程同步的 hashtable, 终于明白了 syncroot 的作用。先说说自动线程同步的 hashtable: 如果 hashtable 要允许并发读但只能一个线程写, 要这么创建 hashtable 实例:
hashtable hashtable = hashtable.synchronized(new hashtable());
这样, 如果有多个线程并发的企图写 hashtable 里面的 item, 则同一时刻只能有一个线程写, 其余阻塞; 对读的线程则不受影响。
测试的代码是这样的:
hashtable _hashtable = hashtable.synchronized(new hashtable());
public void testlock()
{
thread t1 = new thread(new threadstart(syncfunctiona));
thread t2 = new thread(new threadstart(syncfunctionb));
t1.start();
t2.start();
thread.sleep(8000);
console.writeline("hashtable[" _key_a "] = " _hashtable[_key_a]);
}
private void syncfunctiona()
{
lock (_hashtable.syncroot)
{
thread.sleep(5000);
_hashtable[_key_a] = "value set by syncfunctiona";
}
}
private void syncfunctionb()
{
console.writeline("hashtable[" _key_a "] = " _hashtable[_key_a]);
_hashtable[_key_a] = "value set by syncfunctionb";
}
为了清楚的看到效果, 线程 a 用了锁, 并睡眠 5 秒, 睡醒后设置一下 hashtable 里的 item. 线程 b 先读一下 hashtable 里的 item, 再写 hashtable 里的 item。因为对 syncroot 加了锁, 即使线程 b 没有显式的对 hashtable 加锁, 但在 _hashtable[_key_a] = "value set by syncfunctionb" 一句上也会被 hashtable 自动锁住, 直到线程 a 释放掉 syncroot 锁为止。如果线程 a 不是锁 syncroot 而是锁 hashtable 实例本身, 那么线程 b 不会在 _hashtable[_key_a] = "value set by syncfunctionb" 上被自动锁住。
所以, 总结如下:
如果想锁整个 hashtable, 包括读和写, 即不允许并发的读和写, 那应该锁 hashtable 实例;
如果想允许并发的读, 不允许并发的写, 那应该创建 synchronized 的 hashtable, 并对要加锁的一块代码用 syncroot 锁住, 如果不需要对一块代码加锁, 则 hashtable 会自动对单个写的操作加锁。
转载于:https://www.cnblogs.com/hyfei0315/articles/1238627.html
总结
以上是尊龙游戏旗舰厅官网为你收集整理的一个 .net hashtable 的锁的疑惑和解决的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇:
- 下一篇: