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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 张 涛 于 2012-9-12 09:47 编辑
  1. public class TestDeadLock implements Runnable{
  2.     public int flag = 2;
  3.     static Object o1 = new Object();
  4.     static Object o2 = new Object();
  5.    
  6.     public void run(){
  7.         if(flag == 1){
  8.             synchronized(o1){
  9.                 System.out.println("锁住o1");   
  10.                 try {
  11.                     Thread.sleep(5000);
  12.                 }catch(Exception e){}
  13.             }
  14.             
  15.             synchronized(o2){
  16.                 System.out.println("1");
  17.             }
  18.         }
  19.         //疑问:无法死锁
  20.         if(flag == 0){
  21.             synchronized(o2){
  22.                 System.out.println("锁住o2");
  23.                 try {
  24.                     Thread.sleep(5000);
  25.                 }catch(Exception e){}
  26.             }
  27.             
  28.             synchronized(o1){
  29.                 System.out.println("2");
  30.             }
  31.         }
  32.     }
  33.    
  34.     public static void main(String[] args){
  35.         TestDeadLock td1 = new TestDeadLock();
  36.         TestDeadLock td2 = new TestDeadLock();
  37.         td1.flag = 1;
  38.         td2.flag = 0;
  39.         Thread t1 = new Thread(td1);
  40.         Thread t2 = new Thread(td2);
  41.         t1.start();
  42.         t2.start();
  43.     }
  44. }
复制代码
我的理解是,两个线程分别锁住两个对象,再等待获取另一个对象的线程锁,那么此时会形成死锁,但是实际是没有死锁,还能正确运行到结束。

评分

参与人数 1技术分 +1 收起 理由
田建 + 1 鼓励一下!

查看全部评分

5 个回复

倒序浏览
本帖最后由 武庆东 于 2012-9-6 17:55 编辑

public class TestDeadLock implements Runnable{
    public String name;
    static Object os = new Object();
    public TestDeadLock(String name){
        this.name=name;
    }
   
   
    public void run(){
         synchronized(os){
                System.out.println("锁住线程"+name);   
                try {
                    Thread.sleep(5000);
                }catch(Exception e){}
            
            
         
        }
      
    }
   
    public static void main(String[] args){
        TestDeadLock td1 = new TestDeadLock("A");
        TestDeadLock td2 = new TestDeadLock("B");
     
        Thread t1 = new Thread(td1);
        Thread t2 = new Thread(td2);
        t1.start();
        t2.start();
    }
}
注意:使用同步代码块格式
synchronized(同步对象){
  需要同步的代码块
}

回复 使用道具 举报
本帖最后由 全海波 于 2012-9-6 17:48 编辑


  1. <BLOCKQUOTE>
  2. <P> </P>
  3. <P>你拿的根本就不是同一锁,当然不会出现死锁,对你的代码修改如下:</P>
复制代码
  1. 01.public class TestDeadLock implements Runnable{

  2. 02. public int flag = 2;

  3. 03. static Object o1 = new Object();

  4. 04. static Object o2 = new Object();

  5. 05.

  6. 06. public void run(){

  7. 07. if(flag == 1){

  8. 08. synchronized(o1){

  9. 09. System.out.println("锁住o1");

  10. 10. try {

  11. 11. Thread.sleep(5000);

  12. 12. }catch(Exception e){}

  13. 13. }

  14. 14.

  15. 15. synchronized(o2){

  16. 16. System.out.println("1");

  17. 17. }

  18. 18. }

  19. 19. //疑问:无法死锁

  20. 20.
  21. public synchronized void run2()
  22. {
  23. if(flag == 0){

  24. 21. synchronized(o1){

  25. 22. System.out.println("锁住o2");

  26. 23. try {

  27. 24. Thread.sleep(5000);

  28. 25. }catch(Exception e){}

  29. 26. }

  30. 27.

  31. 28. synchronized(o1){

  32. 29. System.out.println("2");

  33. 30. }

  34. 31. }

  35. 32. }
  36. }

  37. 34. public static void main(String[] args){

  38. 35. TestDeadLock td1 = new TestDeadLock();

  39. 36. TestDeadLock td2 = new TestDeadLock();

  40. 37. td1.flag = 1;

  41. 38. td2.flag = 0;

  42. 39. Thread t1 = new Thread(td1);

  43. 40. Thread t2 = new Thread(td2);

  44. 41. t1.start();

  45. 42. t2.start();

  46. 43. }

  47. 44.}
复制代码
回复 使用道具 举报
楼主你的代码是这样走的,flat == 1中的代码,锁住o1时,继续往下执行去尝试锁住o2,这个时候flat == 0中的代码,锁o2的代码可能已经执行完了,所以flat == 1中可以顺利的锁住o2,flat == 0中也是一样,当它去锁o1时锁也应经放开了,
你这个代码修改一点点就行了,思路是让flat == 1中锁住o1等待锁住o2,flat == 0中锁住o2等待锁住o1,让他们俩一门报一个锁并等待另外一个锁,他俩都不放开,所以死锁了
具体代码:
  1. public class TestDeadLock implements Runnable{
  2.     public int flag = 2;
  3.     static Object o1 = new Object();
  4.     static Object o2 = new Object();
  5.    
  6.     public void run(){
  7.         if(flag == 1){
  8.             synchronized(o1){
  9.                 System.out.println("锁住o1");                  
  10.                 try {
  11.                     Thread.sleep(5000);
  12. //锁o2的代码放在已经锁住o1的里面
  13. //睡眠5秒确保另外一个线程已经锁住了o2
  14.                     synchronized(o2){
  15.                         System.out.println("1");
  16.                     }
  17.                 }catch(Exception e){}
  18.             }
  19.             
  20.            
  21.         }
  22.         //疑问:无法死锁
  23.         if(flag == 0){
  24.             synchronized(o2){
  25.                 System.out.println("锁住o2");               
  26.                 try {
  27. //锁o1的代码放在已经锁住o2的里面
  28. //睡眠5秒确保另外一个线程已经锁住了o1
  29.                     Thread.sleep(5000);
  30.                         synchronized(o1){
  31.                     System.out.println("2");
  32.                 }
  33.                 }catch(Exception e){}
  34.             }         
  35.         }
  36.     }
  37.    
  38.     public static void main(String[] args){
  39.         TestDeadLock td1 = new TestDeadLock();
  40.         TestDeadLock td2 = new TestDeadLock();
  41.         td1.flag = 1;
  42.         td2.flag = 0;
  43.         Thread t1 = new Thread(td1);
  44.         Thread t2 = new Thread(td2);
  45.         t1.start();
  46.         t2.start();
  47.     }
  48. }
复制代码
锁住o1
锁住o2

他们俩都抱住一个锁,等待另外一个锁,程序停住了。。。。。ok,楼主复制回去看看,只是把锁资源的代码改改位置就可以了
回复 使用道具 举报
一个拿到o1对象准备去拿o2,另一个拿到o2对象准备去拿o1;
你写的代码意思是:
第一个拿到o1后,锁住o1,sleep 5秒,释放o1,去取o2
第二个拿到o2后,锁住o2,sleep 5秒,释放o2,去取o1;
那么,不管是谁睡5秒后,都会释放掉自己手里的锁的,
改成如下代码:
public class TestDeadLock implements Runnable {
        public int flag = 2;
        static Object o1 = new Object();
        static Object o2 = new Object();

        public void run() {
                if (flag == 1) {
                        synchronized (o1) {
                                System.out.println("锁住o1");
                                // Thread.currentThread().interrupt();         //如果任意一个线程打断的话,就会运行到结束
                                synchronized (o2) {                                //不用加sleep(5000)
                                        System.out.println("1");   //这样的代码才是锁住o1,想要获得o2
                                }
                        }

                }
                // 疑问:无法死锁
                if (flag == 0) {
                        synchronized (o2) {
                                System.out.println("锁住o2");
                                synchronized (o1) {                  //这样的代码才是锁住o2,想要获得o1
                                        System.out.println("2");
                                }
                        }

                }
        }

        public static void main(String[] args) {
                TestDeadLock td1 = new TestDeadLock();
                TestDeadLock td2 = new TestDeadLock();
                td1.flag = 1;
                td2.flag = 0;
                Thread t1 = new Thread(td1);
                Thread t2 = new Thread(td2);
                t1.start();
                t2.start();
        }
}
回复 使用道具 举报
搞定,结贴,谢谢。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马