2

このコードがデッドロックに陥っている理由を誰か教えてください。

public class BrokenOrderingReentredLock implements Runnable {

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    public static void main(String[] args) throws InterruptedException {
        BrokenOrderingReentredLock runnable = new BrokenOrderingReentredLock();
        Thread thread1 = new Thread(runnable, "thread1");
        Thread thread2 = new Thread(runnable, "thread2");
        thread1.start();
        Thread.sleep(500);
        thread2.start();
    }

    @Override
    public void run() {
        try {
            String threadName = Thread.currentThread().getName();
            synchronized (lock1) {
                System.out.println(threadName + " has lock1");
                synchronized (lock2) {
                    System.out.println(threadName + " has lock2");
                        System.out.println(threadName + " reenters lock1");
                        lock1.wait();
                        lock2.wait();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    } }
4

2 に答える 2

0

何が起こっているかというと、thread1 が lock1 でロックを取得し、次に lock2 でロックを取得します。その後、スレッド 1 は lock1.wait を呼び出します。これにより、lock1 のロックが解放され、誰かが notify を呼び出すまでスレッド 1 が待機します (これは発生しません)。

スレッド 2 がやってきて、lock1 のロックを取得します。スレッド 1 がまだロックを保持しているため、ロック 2 でのロックの取得がブロックされます。

lock1.wait と lock2.wait の間にメッセージを入れると、どちらのスレッドもそこまで到達しないため、lock2 のロックが決して解放されないことがわかります。

于 2013-10-02T14:24:30.337 に答える