黑马程序员技术交流社区

标题: 关于死锁的问题 [打印本页]

作者: ankje    时间: 2015-3-8 23:38
标题: 关于死锁的问题
有谁能简单讲解下死锁现象吗?是同步代码块嵌套同步代码块时就有可能出现死锁了吗?
作者: 奔跑的猴子    时间: 2015-3-9 01:55
手机码字就不贴代码了,死锁发生在多线程,并且存在两个锁以上的情况。比如有两个线程同步方法A和B,分别传入了A对象和B对象作为同步监视器,在方法A中点用了B,B中调用了A,那就会出现一种情况。当线程1访问A方法的时候,会把A加锁了,在执行过程中,CPU切换到了线程2访问了B方法,对B方法加锁了。当B方法里面调用A方法的时候,线程2判断A方法正在被线程1调用加锁中,于是进入阻塞状态等待线程1执行完毕。同理,CPU切换回线程1的执行,当执行到A方法调用B方法的时候,发现B方法此时被加锁了,于是线程1进入阻塞状态。此时就是死锁。相互等待
作者: jiangwenjun    时间: 2015-3-9 03:23
死锁的关键在 synchronized()  括号里你所定义的对象是否为同一对象!毕老师说的是由可能,只要你明白具体synchronized()  括号里要放什么,你就可以不会出现死锁
作者: qq10763582    时间: 2015-3-9 11:31
死锁代码例子:
  1. class A{
  2.         public synchronized void test_A(B b){
  3.                         System.out.println("线程:"+Thread.currentThread().getName()+"调用了A类的 test_A方法");

  4.                         b.last_B();
  5.         }
  6.        
  7.         public synchronized void last_A(){
  8.                 System.out.println("线程:"+Thread.currentThread().getName()+"调用了A类的 last_A方法");
  9.         }
  10. }

  11. class B{
  12.         public synchronized void test_B(A a){
  13.                         System.out.println("线程:"+Thread.currentThread().getName()+"调用了A类的 test_A方法");
  14.                         a.last_A();
  15.         }

  16.         public synchronized void last_B(){
  17.                         System.out.println("线程:"+Thread.currentThread().getName()+"调用了B类的 last_B方法");
  18.         }
  19. }

  20. class DeadLock implements Runnable
  21. {
  22.         A a=new A();
  23.         B b=new B();
  24.        
  25.         public void input(){       
  26.           System.out.println("线程:"+Thread.currentThread().getName()+"主线程运行");
  27.                 a.test_A(b);
  28.         }
  29.         public void run(){
  30.                 b.test_B(a);       
  31.         }
复制代码


上面A和B类的方法都是同步方法,也就是A,B对象都是同步锁。程序中两个线程执行,主线程执行了DeadLock对象的input方法,另一个线程执行DeadLock的run方法。假设主线程运行后,其中input方法中调用了b对象的test_A方法,进入test_A方法后,在调用该方法中的a.last_A(),该线程对A对象加锁。假设此时另一个线程抢到了cpu执行权,在此时切换到另一个线程运行了,子线程开始运行run方法,run方法中调用了b对象的test_B()方法,进入test_B()后,在执行方法a.last_A()前子线程会对B 对象加锁。如果此时主线程再次获得执行权,想执行b.last_B()时,但是子线程正保存着对B对象的加锁,所以主线程开始进入阻塞。而子线程想要运行a.last_A()时,而主线程正保存着对A对象的加锁,两个线程相互等待着对方释放锁,所以就出现了死锁。





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