无论您使用
System.out.print还是,都没有什么区别
System.out.format:它们基本上是在做同一件事。
如果
Gaston.bow(Alphonse)在
Alphonse.bow(Gaston)和的开始之间开始执行,则在此处发生死锁
bower.bowBack(Alphonse)(反之亦然):两个线程正在等待另一个线程持有的监视器,因此发生死锁。
出现这种情况不一致,因为它依赖于一个微妙的时机的问题,这取决于线程是如何安排-
这是可能的,
Alphonse.bow并且
bower.backBack(Alphonse)完成前
Gaston.bow被执行,所以看起来没有僵局。
解决此问题的经典方法是对锁进行排序,以使第一个锁每次都首先获取相同的锁。这样可以防止发生死锁:
public void bow(Friend bower) { // Method no longer synchronized. int firstHash = System.identityHashCode(this); int secondHash = System.identityHashCode(bower); Object firstMonitor = firstHash < secondHash ? this : bower; Object secondMonitor = firstHash < secondHash ? bower : this; synchronized (firstMonitor) { synchronized (secondMonitor) { // Code free (*) of deadlocks, with respect to this and bower at least. } }}
(*)这不是 很 保证自由是僵局,因为
System.identityHashCode可以换取不同的对象相同的值; 但这不太可能。
这是生日悖论的一种应用:如果只有两个监视器,则发生碰撞的机会约为10
^ -18;但是如果您的显示器> 77k,则很可能发生碰撞。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)