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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨习平 中级黑马   /  2012-8-15 08:12  /  1610 人查看  /  6 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

多线程中死锁是怎么回事?举两个案例详细讲讲

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 新人发帖,赞一个!

查看全部评分

6 个回复

倒序浏览
  1. public class DeadLockDemo {
  2.         public static void main(String[] args) {
  3.                 Thread t1 = new Thread(new Test(true));
  4.                 Thread t2 = new Thread(new Test(false));
  5.                 t1.start();
  6.                 t2.start();
  7.         }

  8. }

  9. class MyLock
  10. {
  11.         static Object locka = new Object();
  12.         static Object lockb = new Object();
  13. }

  14. class Test implements Runnable
  15. {
  16.         private boolean flag;
  17.         Test(boolean flag)
  18.         {
  19.                 this.flag = flag;
  20.         }

  21.         public void run()
  22.         {
  23.                 if(flag)
  24.                 {
  25.                         while(true)
  26.                         {
  27.                                 synchronized(MyLock.locka)
  28.                                 {
  29.                                         System.out.println(Thread.currentThread().getName()+"...if locka ");
  30.                                         synchronized(MyLock.lockb)
  31.                                         {
  32.                                                 System.out.println(Thread.currentThread().getName()+"..if lockb");                                       
  33.                                         }
  34.                                 }
  35.                         }
  36.                 }
  37.                 else
  38.                 {
  39.                         while(true)
  40.                         {
  41.                                 synchronized(MyLock.lockb)
  42.                                 {
  43.                                         System.out.println(Thread.currentThread().getName()+"..else lockb");
  44.                                         synchronized(MyLock.locka)
  45.                                         {
  46.                                                 System.out.println(Thread.currentThread().getName()+".....else locka");
  47.                                         }
  48.                                 }
  49.                         }
  50.                 }
  51.         }
  52. }
复制代码
在上面那代码中存在着两个锁locka和lockb,和两个线程t1,t2,当t1拿到locka锁,申请lockb锁,但是此时t2已经拿到lockb锁,而它也在申请locka锁,这时候他们分别都拿着对方锁要的锁不放,这样就就会一直僵持下去,就这样一直消耗着系统资源。这就形成了死锁
回复 使用道具 举报
//死锁,代码
public class Deadlock {


        private static boolean flase;

        public static void main(String[] args) {
                //
                Thread a = new Thread(new Test(true));
                Thread b = new Thread(new Test(flase));
                a.start();
                b.start();

        }

}
//死锁例子代码
class Test implements Runnable{
        static Object a=new Object();
        static Object b = new Object();
        private boolean flag;
        Test(boolean flag){
                this.flag=flag;
        }
        public void run(){
                if (flag){
                        synchronized (a)//t1 进来,就锁上了,不过他再往下执行还需要B锁,才可以,
                        {
                                System.out.println("a lock ,需要B");
                                synchronized (b)
                                {
                                        System.out.println("B lock ,需要A");
                                }
                        }
                }
                else{
                        synchronized (b)///t2 进来,就锁上了,不过他再往下执行还需要a锁,才可以
                        {
                                System.out.println("B lock ,需要A");
                                synchronized (a)
                                {
                                        System.out.println("a lock ,需要B");
                                }
                        }
                       
                }
        }
}

在多线程中,当我们嵌套使用,同步的,时候,就有可能出现,死锁的情况,
像例子中,
T1 进程需要 T2进程的锁,而T2需要T1的锁,
应为他们是同步代码块,所以,2个进程都需要,彼此的锁,但他们都不会放,会一直等待下去,就形成了死锁的情况,
当进程多的时候,嵌套锁就更容易,形成,死锁,
所有,我们同步代码的时候,不提倡,嵌套锁,
1.5 以后,也出现了,LOCK,显形锁(代码中可以看到的锁,)来替代,同步中看不到的锁,。更方便使用。
回复 使用道具 举报
产生死锁的原因是A锁和B锁互相等待,直接上代码
  1. package test;



  2. class  Lock
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 PersonA p1 = new PersonA("林青霞",20,1);
  7.                 PersonA p2 = new PersonA("麦蒂",40,0);
  8.                 Thread t1 = new Thread(p1);
  9.                 Thread t2 = new Thread(p2);
  10.                 t1.start();
  11.                 t2.start();
  12.                 t1.run();
  13.                 t2.run();

  14.         }
  15. }

  16. class PersonA implements Runnable
  17. {
  18.         //可以定义两个锁,为了保证唯一性这里定义为静态
  19.         static String a = new String("A锁");
  20.         static String b = new String("B锁");

  21.         String name;
  22.         int age;
  23.         int sexual;//0代表男人,1代表女人
  24.         public PersonA(String name,int age,int sexual)
  25.         {
  26.                 this.name=name;
  27.                 this.age=age;
  28.                 this.sexual=sexual;
  29.         }
  30.         public void run()
  31.         {
  32.                 while (true)
  33.                 {
  34.                         if (sexual>0)
  35.                         {
  36.                                 synchronized(a)//t1进来上了a锁,
  37.                                 {
  38.                                         {
  39.                                                 System.out.print("女人***");
  40.                                         }
  41.                                         synchronized(b)//此时b锁已被t2上了,就进不去了所以t1卡在这里
  42.                                         {
  43.                                                 {
  44.                                                         System.out.print(this.name);
  45.                                                         System.out.print("--");
  46.                                                         System.out.println(this.age);
  47.                                                 }
  48.                                         }
  49.                                 }
  50.        
  51.                                
  52.                         }
  53.                         else
  54.                         {
  55.                                 synchronized(b)//t2进来上了b锁,
  56.                                 {
  57.                                         {
  58.                                                 System.out.print("男人***");
  59.                                         }
  60.                                         synchronized(a)//此时a锁已被t1上了,就进不去了所以t2卡在这里;于是互相卡住
  61.                                         {
  62.                                                 {
  63.                                                         System.out.print(this.name);
  64.                                                         System.out.print("--");
  65.                                                         System.out.println(this.age);
  66.                                                 }
  67.                                         }
  68.                                 }
  69.        
  70.                                
  71.                         }
  72.                 }
  73.                
  74.         }
  75. }
复制代码
回复 使用道具 举报
在多线程中,最容易出现死锁的案例就是,不是使用的同一把锁,比如如下代码:

public class TickDemo {
/**
  * @param args
  */
public static void main(String[] args) {
  // TODO Auto-generated method stub
  Tick t=new Tick();
  Thread t1=new Thread(t);
  Thread t2=new Thread(t);
  t1.start();
  try {
   Thread.sleep(10);
  } catch (Exception e) {
   // TODO: handle exception
  }
  t.flag=false;
  t2.start();
}
}
class Tick implements Runnable{
private int tick=1000;
Object obj=new Object();
boolean flag=true;

public void run() {
  // TODO Auto-generated method stub
  if(flag){
   while(true){
    synchronized (obj) {
     show();//问题在这 ,当一个线程进来时拿到 obj的锁,调用show函数,但是shoe函数具备的是this的锁,就会出现死锁
    }
   }
  }
  else
   while(true){
    show();
   }
}
public synchronized void show(){//这个是用的this锁
  synchronized (obj) {
   if(tick>0){
    try {
     Thread.sleep(10);
    } catch (Exception e) {
     // TODO: handle exception
    }
    System.out.println(Thread.currentThread().getName()+"....."+tick--);
   }
  }
}

}
看一下红色的文字,帮助你理解一下
如果不太清楚 建议你看看毕老师的视频 第十一天的15个视频 关于死锁的 一定会明白
回复 使用道具 举报
  1. class Test implements Runnable
  2. {
  3.         private boolean flag;
  4.         Test(boolean flag)
  5.         {
  6.                 this.flag=flag;
  7.         }
  8.         public void run()
  9.         {
  10.                 if (flag)
  11.                 {
  12.                        
  13.                                 synchronized(MyLock.locka)[color=Red]a锁里面有b锁[/color]
  14.                                 {
  15.                                         System.out.println("if locka");
  16.                                         synchronized(MyLock.lockb)
  17.                                         {
  18.                                                 System.out.println("if lockb");
  19.                                         }
  20.                                 }
  21.                         }
  22.                
  23.                 else
  24.                 {
  25.                                 synchronized(MyLock.lockb)[color=Red]b锁里面有a锁[/color]
  26.                                 {
  27.                                         System.out.println("else lockb");
  28.                                         synchronized(MyLock.locka)
  29.                                         {
  30.                                                 System.out.println("else locka");
  31.                                         }
  32.                                 }
  33.                         }
  34.                 }
  35.         }

  36. class MyLock
  37. {
  38.         static Object locka = new Object();
  39.         static Object lockb = new Object();
  40. }

  41. class  DeadLockTest
  42. {
  43.         public static void main(String[] args)
  44.         {
  45.                 Thread t1=new Thread(new Test(true));
  46.                 Thread t2=new Thread(new Test(false));
  47.                 t1.start();
  48.                 t2.start();
  49.         }
  50. }
复制代码
两个锁相互要,就形成了死锁。就像买了杯豆浆,你拿着吸管,我拿着豆浆,你问我要豆浆,我问你要吸管,到最后咱俩谁都别喝。哈哈。
回复 使用道具 举报
李菁 中级黑马 2012-8-15 11:51:16
7#
同一个应用程序需要并行处理多件任务,那就可以创建多个线程。但是线程多了,往往会出现冲突,使程序无法再进行下去了。这就是“死锁”。
举个例子,就像3个人在玩3个球。规则:每个人都必须先拿到自己左手边的球,才能拿自己右边的球,两手都有球之后,才能把球都放下。
如果三个人刚好都只拿到左手边的球,都等着拿右手边的球,但是因为谁都不能放手,所以三个人都在等待。这就造成了死锁
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马