黑马程序员技术交流社区

标题: 关于死锁问题,求助看看哪里错了 [打印本页]

作者: 646245771    时间: 2014-7-9 16:36
标题: 关于死锁问题,求助看看哪里错了
本帖最后由 646245771 于 2014-7-10 12:02 编辑
  1. class Demo10
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 new Thread(new Tecket(true)).start();
  6.                 new Thread(new Tecket(false)).start();
  7.         }
  8. }

  9. class Tecket implements Runnable
  10. {
  11.         private boolean flag;

  12.         Object locka = new Object();
  13.         Object lockb = new Object();

  14.         Tecket(boolean flag)
  15.         {
  16.                 this.flag = flag;
  17.         }

  18.         public void run()
  19.         {
  20.                 if(flag)
  21.                 {
  22.                         synchronized(locka)
  23.                         {
  24.                                 System.out.println(Thread.currentThread().getName()+"if locka");

  25.                                 synchronized(lockb)
  26.                                 {
  27.                                         System.out.println(Thread.currentThread().getName()+"if lockb");
  28.                                 }
  29.                         }               
  30.                 }
  31.                 else
  32.                 {
  33.                         synchronized(lockb)
  34.                         {
  35.                                 System.out.println(Thread.currentThread().getName()+"else lockb");
  36.                         
  37.                                 synchronized(locka)
  38.                                 {
  39.                                         System.out.println(Thread.currentThread().getName()+"else locka");
  40.                                 }
  41.                         }        
  42.                 }
  43.         }
  44. }
复制代码



求助看看我哪里错了。。。然后请详细的告诉我具体的原因。。。{:3_49:} 下午一觉醒来,也迷糊了,看了半天也没找出来具体哪里错了。。。求助啊。。。
单独创建一个类存放锁对象,这个方法我知道,并且运行之后是一个死锁。我的纠结的问题是,我的这段代码哪里出现错误了?难道不能在多线程的类中创建 锁对象 吗? 同步代码块的锁对象,不是可以是任意对象吗?

作者: 646245771    时间: 2014-7-9 16:59
求助啊...{:3_65:}   这个问题不解决,我一下午脑袋里始终都是这个问题....
作者: 面向大众    时间: 2014-7-9 17:19
楼主需要单例设计2个锁,这样才能保证if和else中的锁只有locka和lockb 而不是4个锁
作者: Darkhorse′Xa    时间: 2014-7-9 17:50
本帖最后由 Darkhorse′Xa 于 2014-7-9 17:54 编辑

可以这么理解,线程A执行到同步代码块中拿到了locka的锁,这时候Cpu切换了马上挂起这个线程,执行线程B,线程B开始执行进入同步代码块当中拿到了lockb的锁.现在就可以试着理解一下,A线程拿着了locka锁要进lockb就需要lockb的锁而这个锁在B线程手里.,同理:B线程拿着的是lockb的锁想要进locka的代码块中但是这个锁是在A线程手里,这两者谁都无法再进入下一个同步代码块当中.就产生了死锁(一旦一个对象锁有人持有其他线程就无法再进入)程序就停在这了!synchronized的嵌套就很容易产生死锁的问题!这么说不知道能不能理解
作者: yangcy    时间: 2014-7-9 17:55
给你一个参考
  1. class DeadLock{
  2.         public static void main(String[] args){
  3.                 TestDeadLock a=new TestDeadLock(true);
  4.                 TestDeadLock b=new TestDeadLock(false);
  5.                 Thread t1=new Thread(a);
  6.                 Thread t2=new Thread(b);
  7.                 t1.start();
  8.                 t2.start();
  9.         }
  10. }
  11. class TestDeadLock implements Runnable{
  12.         private boolean flag;
  13.         TestDeadLock(boolean flag){
  14.                 this.flag=flag;
  15.         }
  16.         public void run(){
  17.                 if (flag==true){
  18.                         synchronized(MyLock.lock1){
  19.                                 System.out.println(Thread.currentThread().getName()+"...if lock1");
  20.                                 synchronized(MyLock.lock2){
  21.                                         System.out.println(Thread.currentThread().getName()+"...if lock2");                       
  22.                                 }
  23.                         }
  24.                 }
  25.                 else{
  26.                         synchronized(MyLock.lock2){
  27.                                 System.out.println(Thread.currentThread().getName()+"...else lock2");
  28.                                 synchronized(MyLock.lock1){
  29.                                         System.out.println(Thread.currentThread().getName()+"...else lock1");                       
  30.                                 }
  31.                         }
  32.                 }
  33.         }

  34. }
  35. class MyLock{
  36.         static final Object lock1=new Object();
  37.         static final Object lock2=new Object();       
  38. }
复制代码


作者: 646245771    时间: 2014-7-9 18:00
yangcy 发表于 2014-7-9 17:55
给你一个参考。

这个写法我知道,我的意思是我的程序哪里出错了? 锁对象不能在程序里面创建吗?
作者: yangcy    时间: 2014-7-9 18:13
646245771 发表于 2014-7-9 18:00
这个写法我知道,我的意思是我的程序哪里出错了? 锁对象不能在程序里面创建吗? ...

你的程序中,创建锁的代码有错:
Object locka = new Object();
Object lockb = new Object();
这两个需设成静态的。
原因:
new Thread(new Tecket(true)).start();
new Thread(new Tecket(false)).start();
你创建了两个对象,如果锁不是静态的话,那么locka 不是同一个,而且lockb 也不是同一个。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2