在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时极有可能会阻塞。这两个块都不会结束,因为每个线程都在等待另一个线程退出弓。
答案 0 :(得分:1)
从Java教程:实际上,静态嵌套类在行为上是一个顶级类,它嵌套在另一个顶级类中以方便打包。
你可以从Deadlock中删除Friend并将其作为外部类而不改变行为。
'static'指的是访问外部类中的变量和方法。与静态(类)方法一样,静态嵌套类不能直接引用其封闭类中定义的实例变量或方法 - 它只能通过对象引用来使用它们。
我不认为它说“没有任何静态类的实例”。外部类不能是静态的,嵌套类实际上是外部类。
虽然好问题 - 我最近经历了这个例子并没有想到这一点。
答案 1 :(得分:0)
编辑:即使创建一个线程比调用方法要慢得多,第一次加载它们的时间也会更长。
正如代码所示,这会导致死锁,因为加载方法所需的时间会有效地对齐两个线程,因为在加载方法之前无法调用这些方法。
如果在线程启动之间添加以下行,则不会出现死锁。
Thread.sleep(50);
类似地,如果在创建线程之前调用方法以确保加载方法,那么也不会出现死锁,因为时间现在取决于线程的启动。
alphonse.bow(gaston);
前言答案。
恕我直言,你不太可能陷入僵局。如果你反复执行这些任务,他们最终会陷入僵局。您只在不同时间执行一次这些操作。这是因为启动新线程所花费的时间比获取两个锁之间的时间要长得多。 (100倍或更多差异。)
我希望这可能会在一百次运行中陷入僵局,但可能更不常见。
据说没有任何静态类的实例,对吧?
不知道这是什么意思,因为Friend
有两个实例没有Deadlock
的实例