黑马程序员技术交流社区

标题: 嵌套锁,造死锁问题! [打印本页]

作者: 葛旭东    时间: 2012-10-8 13:40
标题: 嵌套锁,造死锁问题!
本帖最后由 葛旭东 于 2012-10-8 22:03 编辑

  1.          <div class="blockcode"><blockquote>class Test implements Runnable{
  2. private boolean flag;
  3. Test(boolean flag){
  4. this.flag = flag;
  5. }
  6. Object obj1 = new Object();
  7. Object obj2 = new Object();
  8. public void run(){
  9. if(flag){
  10. synchronized(obj1){
  11. System.out.println(Thread.currentThread().getName()+"  if---obj1");
  12. synchronized(obj2){
  13. System.out.println(Thread.currentThread().getName()+"  if---obj2");
  14. }
  15. }
  16. }
  17. else{
  18. synchronized(obj2){
  19. System.out.println(Thread.currentThread().getName()+"  else---obj2");
  20. synchronized(obj1){
  21. System.out.println(Thread.currentThread().getName()+" else---obj1");
  22. }
  23. }
  24. }
  25. }
  26. }
  27. public class DeadLockTest {

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

  29.        Thread t1 = new Thread(new Test(true),"1号");
  30.        Thread t2 = new Thread(new Test(false),"2号");
  31.        t1.start();
  32.        t2.start();
  33. }

  34. }
复制代码
这个程序使用两个不同的锁,运行后好像不能造成死锁现象。即使添加循环后多次打印也不会出现死锁,为什么?
老毕的视频中的执行过程中很容易就死锁了。。。
作者: 郭阳    时间: 2012-10-8 14:16

你这里建了俩 对象。。。。里面的flag,锁啥的都不共享。。。。。

传一个对象进去就欧了

给你改了改代码   加个循环

  1. class Test implements Runnable{
  2. private boolean flag=true;

  3. Object obj1 = new Object();
  4. Object obj2 = new Object();

  5. public void run()
  6. {
  7. while(true)
  8. {
  9. if(flag)
  10. {
  11.          synchronized(obj1)
  12.         {
  13.                 System.out.println(Thread.currentThread().getName()+"  if---obj1");
  14.                  synchronized(obj2)
  15.                 {
  16.                          System.out.println(Thread.currentThread().getName()+"  if---obj2");
  17.                 }
  18.          }
  19.          flag=false;
  20. }
  21. else
  22. {
  23.          synchronized(obj2)
  24.         {
  25.                  System.out.println(Thread.currentThread().getName()+"  else---obj2");
  26.                  synchronized(obj1)
  27.                 {
  28.                         System.out.println(Thread.currentThread().getName()+" else---obj1");
  29.                  }
  30.         }
  31.         flag=true;
  32. }
  33. }
  34. }
  35. }
  36. class DeadLockTest {

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

  38.        Test test=new Test();
  39.            Thread t1 = new Thread(test,"1号");
  40.        Thread t2 = new Thread(test,"2号");
  41.        t1.start();
  42.        t2.start();
  43. }

  44. }
复制代码

作者: 葛旭东    时间: 2012-10-8 14:57
可是老毕视频中确实传入了两个对象new Test(true)和new Test(false),为什么可以呢?
作者: 张丽    时间: 2012-10-8 15:21
首先你要知道,使用多线程是因为有代码需要被重复执行很多次,所以多创建个线程,让CPU进行切换着执行,提高感观性,用锁是为了解决线程安全问题的。你这个题中如果加上for()循环,第一个线程进来拿到obj1这个锁,第二个线程进来拿到obj2这个锁,第一个线程要执行下面的代码需要拿到obj2这个锁,第二个线程需要拿到obj1这个锁,但是两个线程都在循环中,没有出去,谁也拿不到对方的锁,就造成死锁了。第一个线程调用了start()后需要改标记。
作者: 郭阳    时间: 2012-10-8 16:07
葛旭东 发表于 2012-10-8 14:57
可是老毕视频中确实传入了两个对象new Test(true)和new Test(false),为什么可以呢? ...

能贴下毕老师的 代码吗

作者: 葛旭东    时间: 2012-10-8 16:33
  1. class Test implements Runnable{
  2.         private boolean flag;
  3.         Test(boolean flag){
  4.                 this.flag = flag;
  5.         }
  6.         public void run(){
  7.                 if(flag){
  8.                         synchronized(MyLock.obj1){
  9.                                 System.out.println(Thread.currentThread().getName()+"  if---obj1");
  10.                                 synchronized(MyLock.obj2){
  11.                                         System.out.println(Thread.currentThread().getName()+"  if---obj2");       
  12.                                
  13.                                 }
  14.                         }
  15.                         flag  = false;
  16.                 }
  17.                 else{
  18.                         synchronized(MyLock.obj2){
  19.                                 System.out.println(Thread.currentThread().getName()+"  else---obj2");
  20.                                 synchronized(MyLock.obj1){
  21.                                         System.out.println(Thread.currentThread().getName()+"  else---obj1");
  22.                                
  23.                                 }
  24.                         }
  25.                         flag = true;
  26.                 }
  27.         }
  28.         }
  29. class MyLock{
  30.         static Object obj1 = new Object();
  31.         static Object obj2 = new Object();
  32. }
  33. public class DeadLockTest {

  34.         public static void main(String[] args) {
  35.                Thread t1 = new Thread(new Test(true));
  36.                Thread t2 = new Thread(new Test(false));
  37.                t1.start();
  38.                t2.start();

  39.         }

  40. }
复制代码
老毕原代码
作者: 葛旭东    时间: 2012-10-8 16:39
是两个锁的问题,本类中定义的两个锁,如果一个new Test(),可以死锁,而两个new Test()达不到死锁效果;
而新建类中的两个锁,在两个new Test()可以达到死锁效果。
作者: 郭阳    时间: 2012-10-8 16:52
本帖最后由 郭阳 于 2012-10-8 16:54 编辑
葛旭东 发表于 2012-10-8 16:39
是两个锁的问题,本类中定义的两个锁,如果一个new Test(),可以死锁,而两个new Test()达不到死锁效果 ...

你注意看代码了吗 虽然是两个对象,毕老师两个对象用的是同一个锁

在一个类中定义了一个静态的锁

其实理论上和传一个对象是相同的
你之前之所以不能死锁,是因为两个线程各跑各的,锁虽然是同一个名字,但是封装在两个对象中,不是同一个锁,所以互相都影响不到对方。
作者: 葛旭东    时间: 2012-10-8 17:07
{:soso_e179:}你看的的确仔细啊,确实是一个静态锁。多谢指教!!!{:soso_e183:}




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