none
lock问题 RRS feed

  • 问题

  • List<T> l = new List<T>();//T是一个自定义类
    有一个a线程,执行下列代码:
    lock(l){
        l=new List<T>();
    }
    另一b线程,执行下列代码:
    foreach(T t in l){
        Monitor.Enter(t);
        //随便干点什么
        Monitor.Exit(t);
    }
    这2个线程同步执行,b先进入Monitor.Enter(t),这时候a线程是等待呢还是能执行下去?如果能执行下去那么b线程操作的l集合不就前后不一致了???
    如果不能执行下去,但b线程并没有锁住l,只是锁住了l里面的元素,a为什么不能执行下去?
    2009年6月28日 3:23

答案

  • 如果a中的new List<T>没有结束,b中的foreach循环需要等待!
    你如果这样加锁的话,只能保证在实例化List<T>的过程中,不会启动b中的循环,并不能保证循环使用的I是新的,还是旧的!
    周雪峰
    • 已标记为答案 HUNDRED 2009年6月29日 2:34
    2009年6月29日 2:13
    版主

全部回复

  • 你好!
         如果b先进入Monitor.Enter(t),这时候a线程是等待呢还是能执行下去,主要看a这个时候正在执行的代码是什么,如果a想访问t,就需要等待,如果不是的话,a会照常执行!
    周雪峰
    2009年6月28日 6:37
    版主
  • 这就要看你要做什么了,都做不同的事情,线程之间无所谓是否要互锁了。。
    我的博客,最近新写了一个Windows Mobile 6.5 Widget开发的文章,欢迎捧场
    尽力回答每一个问题,但不代表一定正确,希望初学者能够多自己尝试。。共勉。。:)
    2009年6月28日 11:30
    版主
  • 你好!
         如果b先进入Monitor.Enter(t),这时候a线程是等待呢还是能执行下去,主要看a这个时候正在执行的代码是什么,如果a想访问t,就需要等待,如果不是的话,a会照常执行!
    周雪峰

    a线程执行的是l=new List<T>();这句,也就是再new 一个实例,并将l指向这个新实例。
    b线程干的就是和t相关的操作。
    如果a执行下去了,那么l所指向的实例就变了,b线程再次执行的时候,他所操作的l集合不就不一样了吗?

    就是这个地方没想明白。。。^-^
    2009年6月29日 1:19
  • 如果a中的new List<T>没有结束,b中的foreach循环需要等待!
    你如果这样加锁的话,只能保证在实例化List<T>的过程中,不会启动b中的循环,并不能保证循环使用的I是新的,还是旧的!
    周雪峰
    • 已标记为答案 HUNDRED 2009年6月29日 2:34
    2009年6月29日 2:13
    版主