Java 两个对象如何同时获得锁?

Java 两个对象如何同时获得锁?,java,multithreading,locking,Java,Multithreading,Locking,以下代码使用Lock对象以避免死锁情况 在函数impendingBow中,两个对象如何同时获得锁: 当前对象和好友鲍尔 myLock = lock.tryLock(); yourLock = bower.lock.tryLock(); 是因为它是两个不同的物体吗? 如果是,是否意味着对少数对象使用一个锁就足够了 有人能解释一下我们如何在这个实现中避免死锁吗 这是完整的代码: public class Safelock { static class Friend {

以下代码使用Lock对象以避免死锁情况

  • 在函数impendingBow中,两个对象如何同时获得锁: 当前对象和好友鲍尔

    myLock = lock.tryLock();
    yourLock = bower.lock.tryLock();
    
  • 是因为它是两个不同的物体吗? 如果是,是否意味着对少数对象使用一个锁就足够了

  • 有人能解释一下我们如何在这个实现中避免死锁吗 这是完整的代码:

      public class Safelock {
        static class Friend {
           private final String name;
           private final Lock lock = new ReentrantLock();
    
        public Friend(String name) {
            this.name = name;
        }
    
        public String getName() {
            return this.name;
        }
    
        public boolean impendingBow(Friend bower) {
            Boolean myLock = false;
            Boolean yourLock = false;
            try {
                myLock = lock.tryLock();
                yourLock = bower.lock.tryLock();
            } finally {
                if (! (myLock && yourLock)) {
                    if (myLock) {
                        lock.unlock();
                    }
                    if (yourLock) {
                        bower.lock.unlock();
                    }
                }
            }
            return myLock && yourLock;
        }
    
        public void bow(Friend bower) {
            if (impendingBow(bower)) {
                try {
                    System.out.format("%s: %s has"
                        + " bowed to me!%n", 
                        this.name, bower.getName());
                    bower.bowBack(this);
                } finally {
                    lock.unlock();
                    bower.lock.unlock();
                }
            } else {
                System.out.format("%s: %s started"
                    + " to bow to me, but saw that"
                    + " I was already bowing to"
                    + " him.%n",
                    this.name, bower.getName());
            }
        }
    
        public void bowBack(Friend bower) {
            System.out.format("%s: %s has" +
                " bowed back to me!%n",
                this.name, bower.getName());
        }
    }
    
    static class BowLoop implements Runnable {
        private Friend bower;
        private Friend bowee;
    
        public BowLoop(Friend bower, Friend bowee) {
            this.bower = bower;
            this.bowee = bowee;
        }
    
        public void run() {
            Random random = new Random();
            for (;;) {
                try {
                    Thread.sleep(random.nextInt(10));
                } catch (InterruptedException e) {}
                bowee.bow(bower);
            }
        }
    }
    
    两个对象如何同时获得锁

    两个对象表示两个独立锁。没有所谓的巨锁。有许多单独的锁

    是因为它是两个不同的物体吗?如果是,是否意味着对少数对象使用一个锁就足够了

    是的,当您有一组需要同步修改的对象时,您只能使用一个锁。在这种情况下,您可以选择任何对象或新的专用对象作为组的锁

    有人能解释一下我们如何在这个实现中避免死锁吗

    要避免死锁,必须始终以相同的顺序锁定对象。这就是您要做的,所以程序中没有死锁。更准确地说,当有两个锁A和B时,其中一个线程可以先锁定A,然后锁定B,或者只锁定B(A可能被另一个线程锁定,也可能尚未被另一个线程锁定),或者只锁定A(B可能被另一个线程锁定,也可能尚未被另一个线程锁定)。在这些情况下永远不会出现僵局。如果其中一个线程可以锁定B,那么A,就会出现死锁。事实并非如此


    避免死锁的一个好方法是在锁上编写依赖关系图。每个锁在此图中都是一个对象,依赖项是线程可以按特定顺序获取的锁。然后,要得到一个死锁,必须有一个有循环的。但是,由于等待图是依赖关系图的子图,并且依赖关系图没有循环,因此不可能出现死锁。

    这里有两个不同的锁实例,因此取一个不会影响另一个

    当一个线程获取锁X,另一个线程获取锁Y时,就会发生死锁。然后,第一个线程尝试获取锁Y,并等待它被释放。同时,第二个线程尝试获取锁X,并等待它被释放。由于两个线程都在等待对方,因此操作永远无法完成,线程处于死锁状态


    这里使用的代码,如果无法获取锁,则不会等待。相反,它会立即返回
    false
    。由于线程在获得锁之前不会阻塞,因此此代码段永远不会导致死锁。

    我的错误,只是注意到每个对象都有自己的锁实例。您可以删除您的问题。