谁能帮我解释下以下这段代码是怎么运行的?没有理解,怎么就造成了死锁呢?synchronized关键字到底是锁DemoA还是锁FunA或者锁住的是FunA+Fun2?
按我的理解是应该打印:
DemoA--->进去DemoA中的FunA(DemoB db)方法!!!!!
DemoB--->进去DemoB中的void fun2()方法!!!!!
DemoB--->进去DemoB中的funB(DemoA da)方法!!!!!
DemoA--->进去DemoA中的void fun2()方法!!!!!
实际上打印的内容是:
DemoA--->进去DemoA中的FunA(DemoB db)方法!!!!!
DemoB--->进去DemoB中的funB(DemoA da)方法!!!!!
以下代码出自李兴华多线程第四讲~
- Java code
class DemoA { public synchronized void funA(DemoB db){ System.out.println("DemoA--->进去DemoA中的FunA(DemoB db)方法!!!!!"); try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } db.fun2(); } public synchronized void fun2(){ System.out.println("DemoA--->进去DemoA中的void fun2()方法!!!!!"); }}class DemoB { public synchronized void funB(DemoA da){ System.out.println("DemoB--->进去DemoB中的funB(DemoA da)方法!!!!!"); try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } da.fun2(); } public synchronized void fun2(){ System.out.println("DemoB--->进去DemoB中的void fun2()方法!!!!!"); }}class ThreadDead implements Runnable{ private DemoA da=new DemoA(); private DemoB db=new DemoB(); public ThreadDead(){ new Thread(this).start(); da.funA(db); } public void run(){ db.funB(da); }}public class ThreadDemo16 { public static void main(String[] args) { new ThreadDead(); }}
------解决方案--------------------------------------------------------
两个线程,一个main,一个start启动的。main中da.funA(db)锁住了da,另一个run中db.funB()锁住了db,
funA()和funB()又互调,所以就锁了
------解决方案--------------------------------------------------------
------解决方案--------------------------------------------------------
- Java code
public ThreadDead(){ new Thread(this).start(); da.funA(db); } public void run(){ db.funB(da); }
------解决方案--------------------------------------------------------
同一个实例的同一个synchonized方法不允许一个以上的线程同时访问,记住是同一个实例,如何确定synchronized锁定的是谁呢,就是哪个对象实例调用的这个synchonized方法,它就锁定哪个实例。
上述实例:main线程先去start了一个ThreadDead线程,但是start以后不会马上去执行它的run方法,main线程先走到了da.funA(db),da此时被锁住,main线程sleep,ThreadDead线程run方法起来了运行db.funB(da),此时db被锁住,此时main恢复运行执行db.fun2(),发现db的锁没有被释放,在此等待获得db锁,而ThreadDead执行到da.fun2()时发现da锁也没有释放,他又想获取这个da的锁,结果也在此等待,故此时产生死锁。
解决方案:由于db.fun2()和da.fun2()不涉及的共享数据冲突的问题,把synchonized去掉即可