2017-02-26 115 views
3

我试图在java中自己实现死锁。线程t1和t2都以相同的顺序锁定s1和s2,导致死锁情况。但是,如果我注释掉Line1和Line2调用睡眠方法的线程类,不会发生死锁。我运行该程序超过15次,但删除行1和行2不会导致死锁。了解我的死锁Java示例

所以我的查询是,行1和行2(调用Thread.sleep)是必要的死锁。如果是的话,那么我没有理解死锁。如果不是,它会导致其他JVM死锁?

//Thread DeadLock 

class Threadlock 
{ 
private final static String s1="java"; 
private final static String s2="deadlock"; 
public static void main(String[] args) 
{ 
    Thread t1= new Thread() 
    { 
    public void run() 
    { 
     synchronized(s1) 
     { 
     try { Thread.sleep(100);} 
     catch (Exception e) {} //Line 1 
     synchronized(s2) 
     {} 
     } 
    } 
    }; 

    Thread t2= new Thread() 
    { 
    public void run() 
    { 
     synchronized(s2) 
     { 
     try { Thread.sleep(100);} catch (Exception e) {} //Line 2 
     synchronized(s1) 
     {} 
     } 
    } 
    }; 

    t2.start(); 
    t1.start(); 
    } 
} 
+1

当某些线程同时需要相同的锁时,可能会发生死锁。就你的情况而言,如答案所述,同步块无效 - 他们需要接近“没有时间”。阅读http://tutorials.jenkov.com/java-concurrency/deadlock.html,它可以帮助你更好地理解机制。 –

+0

如果您对第1行和第2行进行注释,请在其他程序的帮助下持续运行您的程序,我相信您会通过eod了解死锁。 –

+0

一个想法:你希望别人花时间帮助你;所以你请花1分钟时间来正确地格式化/全部输入。但仍然upvoted ... – GhostCat

回答

6

如果您删除睡眠,您的方法不会做任何事情。所以它们非常快,以致两个线程同时进入其第一个同步块的概率非常低。但它仍然可能发生。

0

并发程序本质上是不确定的。在实践中,当执行错误的程序时可能会或可能不会观察到潜在的死锁。您提交的代码在调用Thread.sleep时不合格。在你的情况下,睡觉似乎让僵局更加明显,但无论你是否等待一段时间,睡眠都在那里。

1

重点是:您对底层实现没有太多控制。含义:尽管你创建了两个线程并按顺序启动它们;它可能发生在现实中的JVM/OS ... start t1;运行它;然后再开始t2。

为了增加您遇到死锁的机会;保持你的方法至少做几秒钟!

换句话说:“遇到死锁”是​​一种函数,它取决于您的方法的实际运行时间底层实现的详细信息。

+2

Upps。正确。如果第一个人进入关键部分并停留在那里,那么这不是死锁;另一个不到那里。那么,其他一些死锁。无论如何;我删除了那部分。感谢您的输入! – GhostCat