1

在死锁部分,Java SE 7 教程中,有一个示例,如下所示。我不明白为什么 main 方法可以创建 2 个 STATIC 嵌套对象(实际上它被定义为静态嵌套类)。据说没有任何静态类的实例,对吧?谁能帮我吗?谢谢。

==================================================== ========================================== 阿尔方斯和加斯顿是朋友,也是伟大的信徒礼貌地。一个严格的礼貌规则是,当你向朋友鞠躬时,你必须保持鞠躬,直到你的朋友有机会还鞠躬。不幸的是,这条规则没有考虑到两个朋友可能同时互相鞠躬的可能性。这个示例应用程序 Deadlock 模拟了这种可能性:

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());
            bower.bowBack(this);
        }
        public synchronized 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) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}

当 Deadlock 运行时,极有可能两个线程在尝试调用 bowBack 时都会阻塞。这两个块都不会结束,因为每个线程都在等待另一个退出弓。

4

2 回答 2

1

来自 Java 教程:实际上,静态嵌套类在行为上是一个顶级类,它已嵌套在另一个顶级类中以方便打包。

您可以从内部 Deadlock 中删除 Friend 并将其作为外部类,而不会改变行为。

“静态”是指访问外部类中的变量和方法。与静态(类)方法一样,静态嵌套类不能直接引用在其封闭类中定义的实例变量或方法——它只能通过对象引用来使用它们。

我不认为它在任何地方都说“没有任何静态类的实例”。外部类不能是静态的,嵌套类实际上是外部类。

不过,这是个好问题——我最近浏览了这个例子,并没有考虑到这一点。

于 2012-05-15T06:02:30.270 回答
0

编辑:即使创建线程比调用方法慢得多,但第一次加载它们需要更长的时间。

正如代码所示,这确实会发生死锁,因为加载方法所需的时间有效地对齐了两个线程,因为在加载方法之前无法调用这些方法。

如果在线程启动之间添加以下行,则不会出现死锁。

Thread.sleep(50); 

同样,如果您在创建线程之前调用方法以确保加载方法,您也不会遇到死锁,因为时间现在取决于线程的启动。

alphonse.bow(gaston);

以前的答案。

恕我直言,您极不可能陷入僵局。

如果你反复执行这些任务,它们最终会死锁。您只在不同时间执行一次这些操作。这是因为启动一个新线程所花费的时间比获得两个锁之间的时间要长得多。(100 倍或更多差异。)

我希望这可能会在一百次运行中陷入僵局,但它可能会更少。

据说没有任何静态类的实例,对吧?

不知道这意味着什么,因为有两个Friend实例Deadlock

于 2012-05-15T05:59:51.907 回答