0

我正在通过 Java 线程,特别是死锁概念,我发现下面的代码:

public static void main(String... a) {

    final String o1 = "Lock ";
    final String o2 = "Step ";

    Thread th1 = new Thread() {
        public void run() {
            while (true) {
                synchronized (o1) {
                    synchronized (o2) {
                        System.out.println(o1 + o2);
                    }
                }
            }
        }

    };

    Thread th2 = new Thread() {
        public void run() {
            while (true) {
                synchronized (o2) {
                    synchronized (o1) {
                        System.out.println(o2 + o1);
                    }
                }
            }
        }

    };

    new Thread(th1).start();
    new Thread(th2).start();

}

请根据我的理解解释程序正在做什么上述程序产生死锁的其他方法,请告知,并且上面代码中正在使用的锁是实例级锁。

4

3 回答 3

2

考虑以下场景:

  • th1锁定o1并在有机会锁定之前被中断o2
  • th2锁定o2并尝试锁定o1

两个线程都无法取得进一步进展,并且您遇到了deadlock

您的代码的原始版本(在编辑之前)没有死锁的可能性,因为两个线程都以相同的顺序(o1then o2)获得了两个锁。

于 2012-04-17T13:36:41.467 回答
0

根据您编辑的帖子,th1 可以获得 o1,而 th2 可以获得 o2。然后两个线程都在等待另一个释放他们尚未获得的锁,并且它永远不会发生 ==> 死锁。

于 2012-04-17T13:43:58.480 回答
0

要创建死锁,您需要创建多个线程正在等待其他线程持有的锁的情况。例如:

  • 线程 1 需要 Lock1 和 Lock2
  • 按顺序请求:Lock1、Lock2
  • 线程 2 需要 Lock1 和 Lock2
  • 按顺序请求:Lock2、Lock1

    1. 线程 1 请求 Lock1。
    2. 线程 2 请求 Lock2。
    3. 线程 1 获得 Lock1。
    4. 线程 2 获得 Lock2。
    5. 线程 1 请求 Lock2。
    6. 线程 2 请求 Lock1。
    7. 线程 1 不能拥有 Lock2,线程 2 持有它。/线程 1 等待...
    8. 线程 2 不能拥有 Lock1,线程 1 持有它。/线程 2 等待...

在您的(第一个,未编辑的)示例中,两个线程都以相同的顺序请求它们需要的锁,这非常重要。如果Thread1得到Lock1,Thread2就无法得到Lock2并产生Deadlock,因为它还在等待Lock1。避免了死锁,因为两个线程都尝试以相同的顺序获取锁。

在您的(新的、已编辑的)示例中,可能会发生死锁,如上所述。

于 2012-04-17T13:42:32.817 回答