首页 新闻 赞助 找找看

一道百思不得其解的面试题

0
悬赏园豆:10 [待解决问题]

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

public void test(int i)

{

   lock(this)

 {

   if (i>10)

   {

     i--;

     test(i);

   }

 }

}

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

 

 

我的问题:这里说传入引用类型参数会死锁,我试过几种做法都不能产生死锁

勇敢的肺的主页 勇敢的肺 | 初学一级 | 园豆:173
提问于:2013-04-09 11:32
< >
分享
所有回答(3)
0

把int换成object,也不会死锁,因为这里从头到尾只有当前线程在调用,lock语句执行多少次都无所谓的。

水牛刀刀 | 园豆:6350 (大侠五级) | 2013-04-09 11:47

大侠 能否给我个例子 能产生死锁的例子,就以这个例子为基础弄一个,非常感谢

支持(0) 反对(0) 勇敢的肺 | 园豆:173 (初学一级) | 2013-04-09 13:50
    class Test
    {
        private object a_lock = new object();
        private object b_lock = new object();

        public void M1()
        {
            Console.WriteLine("thread {0} is trying to acquire a_lock in M1", Thread.CurrentThread.ManagedThreadId);
            lock (a_lock)
            {
                Thread.Sleep(2000);
                Console.WriteLine("thread {0} got a_lock, trying to acquire b_lock in M1", Thread.CurrentThread.ManagedThreadId);
                lock (b_lock)
                {
                    Console.WriteLine("thread {0} got both a_lock and b_lock in M1", Thread.CurrentThread.ManagedThreadId);
                }
            }
        }

        public void M2()
        {
            Console.WriteLine("thread {0} is trying to acquire b_lock in M2", Thread.CurrentThread.ManagedThreadId);
            lock (b_lock)
            {
                Thread.Sleep(2000);
                Console.WriteLine("thread {0} got b_lock, trying to acquire a_lock in M2", Thread.CurrentThread.ManagedThreadId);
                lock (a_lock)
                {
                    Console.WriteLine("thread {0} got both a_lock and b_lock in M2", Thread.CurrentThread.ManagedThreadId);
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var printer = new Test();
            Thread t1 = new Thread(() => printer.M1());
            Thread t2 = new Thread(() => printer.M2());

            t1.Start();
            t2.Start();
        }
    }

 

@何海: 

支持(0) 反对(0) 水牛刀刀 | 园豆:6350 (大侠五级) | 2013-04-09 14:06
0
class Program
    {
        static void Main(string[] args)
        {
            TestClass tc = new TestClass();
            System.Threading.Thread t = new System.Threading.Thread(tc.test);
            t.Start(1000);
            System.Threading.Thread t2 = new System.Threading.Thread(tc.test);
            t2.Start(2000);
        }

    }
    public class TestClass
    {
        public void test(object n)
        {
            int i = int.Parse(n.ToString());
            lock (this)
            {
                if (i > 10)
                {
                    i--;
                    test(i);
                }
            }
        }
    }

 

楼上说的很对,但是换成多个线程也不会产生死锁,

因为有i--,

每次i 的传递并非传递的是副本,确实是i已经递减的结果了, 

只会造轮子 | 园豆:2274 (老鸟四级) | 2013-04-09 14:08
0
滴答的雨 | 园豆:3681 (老鸟四级) | 2013-04-09 19:07
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册