zoukankan      html  css  js  c++  java
  • SyncRoot 属性

    转自:http://blog.csdn.net/seamonkey/article/details/583613 

    今天同事告诉我, 锁 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 会自动对单个写的操作加锁。

  • 相关阅读:
    Programming In Lua 第一章
    TCP/IP 第四、五章
    wireshark数据包分析实战 第三、四章
    [MFC.Windows程序设计(第2版) 第一章
    wireshark数据包分析实战 第二章
    C++PrimerPlus第6版 第四章——复合类型
    TCP/IP 第三章
    Linux命令行与脚本编程大全第一章
    Flink的并行度设置
    基于HttpClient的工具类HttpUtil
  • 原文地址:https://www.cnblogs.com/ylemzhang/p/2351405.html
Copyright © 2011-2022 走看看