A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 孔雀东南飞 于 2013-6-10 11:13 编辑

死锁代码:
class Test implements Runnable

{
        private boolean flag;

        Test(boolean flag)

        {
                this.flag = flag;

        }

        public void run()

        {
                if(flag)

                {
                        synchronized(MyLock.locka)

                        {
                                System.out.println("if locka");

                                synchronized(MyLock.lockb)

                                {
                                        System.out.println("if lockb");

                                }

                        }

                }

                else

                {
                         synchronized(MyLock.lockb)
                        {
                                System.out.println("else lockb");

                                synchronized(MyLock.locka)

                                {
                                        System.out.println("else locka");

                                }

                        }
                }

        }

}
class MyLock
{
        static MyLock locka = new MyLock();//定义锁locka

        static MyLock lockb = new MyLock();//定义锁lockb

}
class DeadLockDemo
{
        public static void main(String[] args)

        {
                Thread t1 = new Thread(new Test(true));

                Thread t2 = new Thread(new Test(false));

                t1.start();

                t2.start();

        }

}

死锁理解:

线程t1      start()时,调用new Test(true);的run方法;
线程t2      start()时,调用new Test(false)的run方法;
这里调用的不是同一个Test对象的run方法;

锁locka  和锁lockb是唯一的,不能同时被两个线程共同使用;意思就是locka只能被线程t1或t2使用,lockb只能被线程t1或t2是使用;而不能是locka即被线程t1使用又被线程t2使用。

但是一个线程可以使用多个锁,也就是说线程t1在使用locka的同时还可以使用lockb;t2在使用locka的同时也还可以使用lockb,但某一时刻,locka或lockb只能被一个线程使用。

synchronized(locka),表示其所属线程正使用锁locka;
synchronized(lockb),表示其所属线程正使用锁lockb;

代码解析:
运行结果:
if locka
else lockb

分析:
t1.start()时, 执行到System.out.println("if locka");打印if locka;  若想继续执行synchronized(MyLock.lockb),则必须拿到lockb;
而此时,由于t2.start(),执行属于new Test(false)对象的run()方法,执行到 System.out.println("else lockb");打印else lockb;若想继续执行 synchronized(MyLock.locka),则必须拿到locka;
关键是:  synchronized(MyLock.locka){}中代码还没执行完,因此t1不可能放掉锁locka;synchronized(MyLock.lockb){}中代码还没执行完,因此t2也不可能放掉lockb;而locka 和lockb只能在某一时刻被一个线程拿到,t1在拿到locka的同时还想拿到lockb,t2在拿到lockb的同时还想拿到locka,t1  t2又都不能放弃各自的锁,因此程序陷入僵局。也就是形成了死锁。

评分

参与人数 2技术分 +2 收起 理由
黑马伍哲沂 + 1 给力提问。
刘凯 + 1 很给力!

查看全部评分

7 个回复

倒序浏览
好详细啊  等待大神指正
回复 使用道具 举报
袁梦希 发表于 2013-6-9 14:59
好详细啊  等待大神指正

这么详细应该给2分或3分,不是说技术分可以多给吗!!?
死锁 就是进程间相互争夺资源而形成的一种僵持的状态。
经典案例:哲学家进餐问题
五个哲学家在一圆桌吃饭,只有五只筷子,每两个人中间放一只筷子。规定只有同时拿到两只筷子的人才能用餐。如果每个哲学家都拿起了一只,同时都不愿放弃得到的那只筷子,陷入僵局,最后,最后都饿死了……
其实他们完全可以用手抓着吃,呵呵!(说笑了)上面只是形象的把进程比作哲学家说问题的,计算机不像我们人一样,它底层都是一些什么mos管之类的,只有两种状态开和关,对应二进制0和1。通过程序让他干什么就干什么,所以死锁在多线程中不可避免,但是我们可以人为去控制他尽量避免死锁。。。

评分

参与人数 1技术分 +1 收起 理由
黑马伍哲沂 + 1 很给力!

查看全部评分

回复 使用道具 举报
同步a lockA  嵌套同步b 中lockB,同步c lockB 嵌套同步d lockA,锁的争夺战,僵持不动就死锁了!
回复 使用道具 举报
代码可以用发帖工具栏里专门写代码的工具会更好。两个尖括号。- -
回复 使用道具 举报
嗯,以后会尽量用<>写的。
回复 使用道具 举报
夜默 金牌黑马 2013-6-10 10:48:52
7#
楼主你好  如果帖子的问题已经解决,请把帖子的类型改为“已解决”。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马