none
关于lock的一个疑问? RRS feed

  • 问题

  • 我有一个List<string> list对象。

    一个线程不断的往里面添加string对象。

    另外有一个线程会偶尔去执行一个查找操作,FindMethod(string s)。找到返回true,否则返回false。

    问题: 这样的一个操作。我需不需要使用lock。因为第二个线程没有对list进行修改操作,而只是读取操作。

    请大家帮我解答一下。

    2010年5月19日 8:14

答案

  • 毫不犹豫,这里一定需要的。

    第一,List<T> 的实例方法是线程不安全的。MSDN 上说,List 上的实例方法不能保证线程安全。虽然您只有一个线程在写,一个线程在读,但,这已经构成资源竞争,需要利用 lock 来消除竞争。

    第二,这个场景是一个典型的生产者/消费者问题。必须考虑使用 ReaderWriter 锁。

    建议您使用 ReaderWriterSlim 对象去 Lock List<T>,不要直接用 lock (lock = Monitor.Enter/Exit)。


    Mark Zhou
    2010年5月19日 10:09
  • 你好!

         是否进行同步,主要取决于你的需求,意思就是说,你是否介意在对象添加的过程中读取数据,这是一种不确定状态,有可能已经添加了一部份,有可能还没有添加,也可能添加完毕!

         如果你的需求不介意这种情况,可以不用同步,如果介意,那就必须同步了!


    周雪峰
    2010年5月19日 10:19
    版主

全部回复

  • 毫不犹豫,这里一定需要的。

    第一,List<T> 的实例方法是线程不安全的。MSDN 上说,List 上的实例方法不能保证线程安全。虽然您只有一个线程在写,一个线程在读,但,这已经构成资源竞争,需要利用 lock 来消除竞争。

    第二,这个场景是一个典型的生产者/消费者问题。必须考虑使用 ReaderWriter 锁。

    建议您使用 ReaderWriterSlim 对象去 Lock List<T>,不要直接用 lock (lock = Monitor.Enter/Exit)。


    Mark Zhou
    2010年5月19日 10:09
  • 你好!

         是否进行同步,主要取决于你的需求,意思就是说,你是否介意在对象添加的过程中读取数据,这是一种不确定状态,有可能已经添加了一部份,有可能还没有添加,也可能添加完毕!

         如果你的需求不介意这种情况,可以不用同步,如果介意,那就必须同步了!


    周雪峰
    2010年5月19日 10:19
    版主
  • 你好!

         是否进行同步,主要取决于你的需求,意思就是说,你是否介意在对象添加的过程中读取数据,这是一种不确定状态,有可能已经添加了一部份,有可能还没有添加,也可能添加完毕!

         如果你的需求不介意这种情况,可以不用同步,如果介意,那就必须同步了!


    周雪峰


    按照你的说法,我是不是可以这样来理解: 就是如果我不介意 (当数据还没完全添加进来,读取会失败)这样的一种情况,那么不需要lock也没关系是不是.

    2010年5月19日 13:00
  • 你好!

         是这个意思, mazhou的建议十分重要,Add方法本身就无法保证线程安全,很可能Add执行到中途,而你的读取线程插入进来了,这样会发生无法预料的情况,所以建议你还是加锁来同步!


    周雪峰
    2010年5月19日 13:11
    版主
  • 你好!

         是否进行同步,主要取决于你的需求,意思就是说,你是否介意在对象添加的过程中读取数据,这是一种不确定状态,有可能已经添加了一部份,有可能还没有添加,也可能添加完毕!

         如果你的需求不介意这种情况,可以不用同步,如果介意,那就必须同步了!


    周雪峰


    按照你的说法,我是不是可以这样来理解: 就是如果我不介意 (当数据还没完全添加进来,读取会失败)这样的一种情况,那么不需要lock也没关系是不是.

     

    要是 Add 线程做到一半的时候停下, 把 read 线程调进来,正好 find method 要的就是这个 Add 到一半的 string 。 你会就很高兴地发现 find 到了一个不知道是什么东西的东西。。。

    2010年5月20日 2:23
  • 那么按照你们的意思。还是要加锁来处理比较好了,是吧?
    2010年5月20日 8:31
  • 建议采用 ReaderWriterSlim 加锁。lock 本身是一个语法糖,它只是简单的 Montor.Enter 和 Monitor.Exit,对于有写操作的多线程同步问题,ReaderWriterSlim 提供很好的实现。
    Mark Zhou
    2010年5月20日 10:35
  • 你好!

         是的,最好加锁!


    周雪峰
    2010年5月20日 11:06
    版主