hf

导航

 

问题:根据线程安全的相关知识,分析以下代码,当调用Fun3方法时i>10时是否会引起死锁?并说明理由。

public void Fun3(int i) {
    lock (this) {
        if (i > 10) {
            i--;
            Fun3(i);
        }
    }
}

网上答案是:不会发生死锁,(但有一点int是按值传递的,所以每次改变的都只是一个副本,因此不会出现死锁。但如果把int换做一个object,那么死锁会发生)

------------------------------------------------------------------------------------

不会发生死锁是对的,但和按值传递好像没有什么关系,即使是引用类型还是不会死锁。

关键在于同一个线程里可以循环多次lock一个对象,这种情况下一个线程是怎样也不会死锁的。

即使多个线程也无非是一个等待另一个执行完再执行,同样不会死锁。

但如果这样写:

public void Fun3(int i) {
    lock (this) {
        if (i > 10) {
            i--;
            Action<int> action = Fun3;
            var r = action.BeginInvoke(i, p => { }, null);
            action.EndInvoke(r);
        }
    }
}

这里用BeginInvoke在线程池里执行Fun3,并用EndInvoke等待其执行完成。也就是说lock(this)后又等待另一个线程执行lock(this),这样就造成了循环等待的条件,并发生死锁。

如有不同意见敬请指出,谢谢!

死锁的四个必要条件:

  1. 互斥:一个资源不能同时由多于两个进程使用
  2. 持有并等待:已持有资源的进程需要新资源
  3. 不能抢占:不能从正持有资源的进程里强占资源
  4. 循环等待:若干进程之间形成一种头尾相接的循环等待资源关系

 

  1. Mutual exclusion condition: a resource that cannot be used by more than one process at a time
  2. Hold and wait condition: processes already holding resources may request new resources
  3. No preemption condition: No resource can be forcibly removed from a process holding it, resources can be released only by the explicit action of the process
  4. Circular wait condition: two or more processes form a circular chain where each process waits for a resource that the next process in the chain holds

参见http://en.wikipedia.org/wiki/Deadlock

posted on 2010-07-16 10:06  hf  阅读(597)  评论(0)    收藏  举报