原题目是这样的:
根据线程安全的相关知识,分析以下代码,当调用test方法时i>10时是否会引起死锁?并简要说明理由。
public void test(int i) { lock(this) { if (i>10) { i--; test(i); } } }
我自己调试了一下,不会发生死锁,百度了一下,有人说如果i是引用类型就会死锁,后来我把i改成引用类型也没死锁,在你看来上边这段代码换成引用后会死锁吗?或帮我看看我测试代码是不是没写对?
using System; using System.Collections; using System.Threading; class t { public int i { get; set; } } class s { public void test(object x) { lock (this) { if (((t)x).i > 10) { ((t)x).i = --((t)x).i; test(x); } } } public void test(int x) { lock (this) { if (x > 10) { x = --x; test(x); } } } static void Main() { t x = new t { i = 1111 }; s i = new s(); Thread th = new Thread(new ParameterizedThreadStart(i.test)); th.Start(x); Thread.Sleep(1); i.test(x); } }
另外,我实例化的时候如果把i的值设定大一些,比如5个1的时候,运行就会报栈溢出,这个递归是有终点的啊,为什么值大一些就报这个呢?
应该 不会死锁
1. lock(this) 是锁住当前实例,当前实例只供一个线程使用,直到这个线程离开锁区域,如果两个线程同一个实例 lock就有用了,如下:
Thread th1 = new Thread(i.test) ;
Thread th2 = new Thread(i.test) ;
。
2. 你的test递归,递归方法里有锁,但是都是同一个线程直到递归完,当然不会造成死锁,锁只对其它线程有用。
谢谢你的回答,我的代码中也是2个线程同时访问的呀……他还是没锁
static void Main() { t x = new t { i = 1111 }; s i = new s(); Thread th = new Thread(new ParameterizedThreadStart(i.test)); th.Start(x); Thread.Sleep(1); i.test(x); }
@hexllo:
你这样 怎么会死锁呢,只会等待,等待一个线程完成,另一个再进入。
死锁是 互相等待对方释放才会死锁
lock(this) 这个this,要是个实例化的对象,你的这个根本lock不住
应该 不会死锁
我觉得网上的回答有问题,其实,这个锁定,跟i一点儿关系都没有,而是跟线程执行的实例有关系;
那么多线程执行这个方法的时候,如果每个线程指定的都以一个实例的该方法,一定会死锁的,如果每个线程都运行自己的实例方法,那这个lock,肯定不管用;
嗯,我也这么认为的。
参考一下这段测试代码:
http://www.cnblogs.com/myshell/archive/2010/07/18/1780386.html