实践中的Java并发性:清单8.3。诱导锁定命令以防止死锁

时间:2019-02-14 17:09:34

标签: java multithreading

我无法理解为什么书中清单8.3中提到的代码不容易死锁。当我运行代码时,它不会导致死锁。我从书中汲取了想法并修改了代码。 下面是程序:-

    public class LockOrderingDeadLockSolved {
    private final Object left = new Object();
    private final Object right = new Object();
    private final Object tieLock = new Object();

    public static void main(String[] args) {

        LockOrderingDeadLockSolved obj = new LockOrderingDeadLockSolved();
        int leftHash = System.identityHashCode(obj.left);
        int rightHash = System.identityHashCode(obj.right);
        System.out.println(leftHash +" --- " + rightHash);
        Thread t = new Thread() {
            public void run() {
                if (leftHash < rightHash)
                    obj.leftRight();
                else if (leftHash > rightHash)
                    obj.rightLeft();
                else
                    obj.tieLockMethod();
            }
        };
        Thread t1 = new Thread() {
            public void run() {
                if (leftHash < rightHash)
                    obj.leftRight();
                else if (leftHash > rightHash)
                    obj.rightLeft();
                else
                    obj.tieLockMethod();
            }
        };
        t.start();
        t1.start();

    }

    private void leftRight() {
        synchronized (left) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized (right) {
                System.out.println("Left right -- left right lock");
            }
        }
    }

    private void rightLeft() {
        synchronized (right) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized (left) {
                System.out.println("Right left -- right left lock");
            }
        }
    }

    private void tieLockMethod() {
        synchronized (tieLock) {
            synchronized (left) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (right) {
                    System.out.println("Right left --- tie lock");
                }
            }
        }
    }
}

输出:-

865113938 --- 1442407170

左-右锁

左-右锁

容易死锁的程序:-

public class LockOrderingDeadLock {
private final Object left = new Object();
private final Object right = new Object();

public static void main(String[] args) {
    LockOrderingDeadLock obj = new LockOrderingDeadLock();
    Thread t = new Thread() {
        public void run() {
            obj.leftRight();
        }
    };
    Thread t1 = new Thread() {
        public void run() {
            obj.rightLeft();
        }
    };
    t.start();
    t1.start();

}

private void leftRight() {
    synchronized (left) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        synchronized (right) {
            System.out.println("Left right");
        }
    }
}

private void rightLeft() {
    synchronized (right) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        synchronized (left) {
            System.out.println("Right left");
        }
    }
}

}

1 个答案:

答案 0 :(得分:0)

如果以相同的顺序获取锁,则不会发生死锁。

要使示例死锁,您必须以不同的顺序反复获取相同的锁。可以使用以下代码完成。

private static final Object left = new Object();
private static final Object right = new Object();

public static void main(String[] args) {
    Thread t1 = new Thread(() -> {
        while (true) {
            synchronized (left) {
                synchronized (right) {
                    System.out.println("Left right -- left right lock");
                }
            }
        }
    });
    Thread t2 = new Thread(() -> {
        while (true) {
            synchronized (right) {
                synchronized (left) {
                    System.out.println("Right left -- right left lock");
                }
            }
        }
    });
    t1.start();
    t2.start();
}