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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 山西_李帅 中级黑马   /  2013-4-11 20:42  /  1307 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 山西_李帅 于 2013-4-12 13:30 编辑

谁能帮帮解决下死锁的问题。原理也懂,能不能付代码注视解释一下,万分感谢啊

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

6 个回复

倒序浏览
public class Stack {

LinkedList list = new LinkedList();

public  void push(Object x) {
synchronized(list) {
list.addLast( x );
notify();
}
}

public  Object pop()
throws Exception {
synchronized(list) {
if( list.size() <= 0 ) {
wait();
}
return list.removeLast();
}
}
}


多线程的时候,如果有多个线程push 多个线程 pop 假如某一时刻LinkedList里面没有元素,pop操作的线程就会放弃锁等待,当醒来时可能没有元素或在wait的过程中加入了元素但被其它线程取走了,这时LinkedList为空。

if( list.size() <= 0 ) {
wait();
}
改为
while(list.size() <= 0 ){
        wait();
}

可以将notify() 换成notifyAll() , 否则在多线程时假如每次唤醒的都是pop的线程而LinkedList为空,所有线程就只能永远等待,这里最好使用condition

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
产生死锁的原因:一是系统提供的资源数量有限,不能满足每个进程的使用;二是多道程序运行时,进程推进顺序不合理。产生死锁的必要条件是:1、互斥条件;2、不可剥夺条件(不可抢占);3、部分分配;4、循环等待。  死锁要求两个或者两个以上的线程请求相互的资源,相互都不能释放形成死锁,死锁代码如下:

public void run() {
  if (flag == 0) {
   synchronized (o1)
   {
    try {
     Thread.sleep(2000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    synchronized (o2)
    {
     System.out.println(0);
    }
   }
   
  }
  if (flag == 1) {
   synchronized (o2)
   {
    try {
     Thread.sleep(2000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   
    synchronized (o1)
    {
     System.out.println(1);
    }
   }

}

}

t1锁住了o1,同时要得到o2的操作
t2锁住了o2,同时要得到o1的操作
于是t1等t2释放o2,t2却等t1释放o1
这样就形成了死锁

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
  1. public class TestDeadLock implements Runnable {
  2.         int flag = 0;
  3.         static TestDeadLock tdl3 = new TestDeadLock();
  4.         static TestDeadLock tdl4 = new TestDeadLock();
  5.         public static void main(String[] args) {
  6.                 TestDeadLock tdl1 = new TestDeadLock();
  7.                 TestDeadLock tdl2 = new TestDeadLock();
  8.                 Thread t1 = new Thread(tdl1);
  9.                 Thread t2 = new Thread(tdl2);
  10.                 //flag=0为线程t1的执行标志,flag=2为线程t2的执行标志
  11.                 tdl1.flag = 0;
  12.                 tdl2.flag = 1;
  13.                 t1.setName("t1");
  14.                 t2.setName("t2");
  15.                 t1.start();t2.start();
  16.         }

  17.         public void run() {
  18.                 //这一条语句是线程t1、t2都会执行到的
  19.                 System.out.println("flag="+flag);
  20.                 //线程t1单独执行的部分
  21.                 if(flag == 0) {
  22.                         //线程t1锁定对象tdl3
  23.                         synchronized(tdl3) {
  24.                                 try {
  25.                                         Thread.sleep(1000);
  26.                                 }catch(InterruptedException e) {}
  27.                                 //等待t1解锁,但是由于t1也在等待t2解锁,故这里发生互锁
  28.                                 synchronized(tdl4) {
  29.                                         System.out.println(1);
  30.                                 }
  31.                         }
  32.                 }

  33.                 if(flag == 1) {
  34.                         //线程t2锁定对象tdl4
  35.                         synchronized(tdl4) {
  36.                                 try {
  37.                                         Thread.sleep(1000);
  38.                                 }catch(InterruptedException e) {}
  39.                                 //等待t2解锁,但是由于t2也在等待t1解锁,故这里也发生互锁
  40.                                 synchronized(tdl3) {
  41.                                         System.out.println(0);
  42.                                 }
  43.                         }
  44.                 }       
  45.         }
  46. }
复制代码
希望能帮到你!

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

  导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问。“synchronized”关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性的访问权。当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。

  由于这个原因,在使用“synchronized”关键词时,很容易出现两个线程互相等待对方做出某个动作的情形。代码一是一个导致死锁的简单例子。

//代码一
class Deadlocker {
int field_1;
private Object lock_1 = new int[1];
int field_2;
private Object lock_2 = new int[1];

public void method1(int value) {
  “synchronized” (lock_1) {
   “synchronized” (lock_2) {
    field_1 = 0; field_2 = 0;
   }
  }
}

public void method2(int value) {
  “synchronized” (lock_2) {
   “synchronized” (lock_1) {
    field_1 = 0; field_2 = 0;
   }
  }
}
}

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 范鹏飞 于 2013-4-11 21:42 编辑
  1. class  Demo1
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 DeadLock d = new DeadLock();
  6.                 Thread t1 = new Thread(d);
  7.                 Thread t2 = new Thread(d);

  8.                 t1.start();
  9.                 t2.start();
  10.         }
  11. }
  12. //死锁
  13. class DeadLock implements Runnable
  14. {
  15.         Object obj = new Object();
  16.         boolean flag = true; //一个标记,要让其后的一个线程进来
  17.         //重写Runnable接口中的run方法
  18.         public void run()
  19.         {
  20.                 while(true)
  21.                 {
  22.                         if (flag)
  23.                         {
  24.                                 flag = false;
  25.                                 show1();//使用的锁是this
  26.                         }else
  27.                         {
  28.                                 flag = true;
  29.                                 synchronized (obj)//第一层锁是obj
  30.                                 {                                       
  31.                                         try
  32.                                         {
  33.                                                 Thread.sleep(10);
  34.                                         }
  35.                                         catch (Exception e)
  36.                                         {
  37.                                         }
  38.                                         show2();//使用的是锁this
  39.                                 }
  40.                         }
  41.                
  42.                 }
  43.         }
  44.         //方法一
  45.         public synchronized void show1()//第一层锁是this
  46.         {        
  47.                 try
  48.                 {
  49.                         Thread.sleep(10);
  50.                 }
  51.                 catch (Exception e)
  52.                 {
  53.                 }
  54.                 synchronized(obj)//第二层锁是obj
  55.                 {                        
  56.                         System.out.println("show1..........." );
  57.                 }
  58.         }
  59.         //方法二
  60.         public void show2()
  61.         {
  62.                
  63.                 synchronized(this)//锁是this
  64.                 {
  65.                         System.out.println("show2........." );               
  66.                 }
  67.         }

  68. }
复制代码
死锁主要是嵌套问题,两个线程都互相持有对方的锁,互不相让。产生死锁。

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
死锁:
通常是同步中嵌套同步,锁不同
下面这个例子中就是一个锁中嵌套着另一个锁。而且都在彼此等待着对方。所以产生死锁。
  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.                         synchronized(Mylock.locka)//持着锁locka
  13.                         {
  14.                                 System.out.println("if locka");
  15.                                 synchronized(Mylock.lockb)//等待着锁lockb
  16.                                 {
  17.                                         System.out.println("if lockb");
  18.                                 }
  19.                         }
  20.                 }
  21.                 else
  22.                 {
  23.                         synchronized(Mylock.lockb)//持着锁lockb
  24.                         {
  25.                                 System.out.println("esle locka");
  26.                                 synchronized(Mylock.locka)//等待着锁locka
  27.                                 {
  28.                                         System.out.println("esle locka");
  29.                                 }
  30.                         }
  31.                 }
  32.         }

  33. }

  34. class Mylock
  35. {
  36.         static Object locka=new Object();
  37.         static Object lockb=new Object();
  38. }
  39. class DeadTest
  40. {
  41.         public static void main(String[] args)
  42.         {
  43.                 Thread t1=new Thread(new Test(true));
  44.                 Thread t2=new Thread(new Test(false));
  45.                 t1.start();
  46.                 t2.start();
  47.         }
  48. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马