我为示例线程代码获得的输出的正确逻辑是什么



这是我的示例线程代码。

public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s"
                + "  has bowed to me!%n", 
                this.name, bower.getName());
            synchronized(bower) { //this is the change
                 bower.bowBack(bower);
            }
        }
        public  void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }
    public static void main(String[] args) throws InterruptedException {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
//       Thread.sleep(20);
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}

这将陷入僵局。但是如果我对它做一个小的改变。我没有使用"bower"作为同步块的监视器,而是使用"this",它不会进入死锁。

  public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s"
                + "  has bowed to me!%n", 
                this.name, bower.getName());
            synchronized(this) { //This is the change.
                 bower.bowBack(bower);
            }
        }
        public  void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }
    public static void main(String[] args) throws InterruptedException {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
//       Thread.sleep(20);
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
   }

请帮助我获得上述代码所显示的行为背后的正确原因。

区别在于

synchronized(objectidentifier) {
   // Access shared variables and other shared resources
}

在这里,对象标识符是对对象的引用,该对象的锁与同步语句表示的监视器相关联。

syncd(bower)使用来自bower的监视器,它是一个不同的对象。你为鲍尔做一把锁。由于两个线程都锁定了另一个线程中的对象,因此会发生死锁。

并且同步(这)使用自己的监视器。你为自己的对象做一个锁。线程将对象锁定在相同的线程中,没有人关心。

如果我错了,请纠正我!

你想要实现的是,在向某人鞠躬的同时,你不能鞠躬。

我会向bowBack方法添加synchronized并从bow...()中删除synchronize(this)synchronize(bower)

最新更新