2013-09-27 59 views
1

我正在阅读Oracle的Java Concurrency Tutorial用于解决Java中的DeadLock的替代方案

还有是DeadLock

核心代码的示例:

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()); 
    } 

然后当教程进到LockObject,它提供了一个解决方案来处理由Lock Object僵局。

现在我想知道如果没有使用Lock对象来避免死锁吗?

+1

执行'Lock'行为。 –

+0

这是唯一的选择吗? – hguser

+0

您需要一种超时尝试获取监视器的机制。我认为'Lock'实现使用了一些'sun.misc.Unsafe'逻辑。 –

回答

3

避免死锁的一种方法是通过强制获取两个锁的顺序来打破对称性。例如,你可以说,当开始一个弓时,线程应该总是锁定一个名字以字母顺序排在第一位的朋友,这样任何做弓的线程都必须首先获得对Alphonse的锁定,然后再对Gaston锁定,永远不会反向:

public void bow(Friend bower) { 
     Friend lock = (this.name.compareTo(bower.name)<0)? this : bower); 
     synchronized (lock) { 
      System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName()); 
      bower.bowBack(this); 
     } 
    } 
    public void bowBack(Friend bower) { 
     Friend lock = (this.name.compareTo(bower.name)>0)? this : bower); 
     synchronized (lock) { 
      System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName()); 
     } 
    } 

无锁选项是使用原子变量信号,如果弓已在进行中,并等待,如果有一个:

private static AtomicBoolean bowing = new AtomicBoolean(); 
    public void bow(Friend bower) { 
     while (!bowing.compareAndSet(false, true)) Thread.yield(); 

     System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName()); 
     bower.bowBack(this); 

     bowing.set(false); 
    } 

另一个避免僵局的方式正在使用一个单一的锁而不是两个;两个线程争夺一个锁不能死锁。

private static Object lock = new Object(); 
    public void bow(Friend bower) { 
     synchronized (lock) { 
      System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName()); 
      bower.bowBack(this); 
     } 
    } 

    public void bowBack(Friend bower) { 
     synchronized (lock) { 
      System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName()); 
     } 
    } 
+0

太棒了!我从来没有想过可以像这样使用'synchronized'。顺便说一句,你可以推荐一些关于java中'线程,并发性'的教程吗?由于我在帖子中提到的教程比较高,我需要一些更详细的指导。 :) – hguser

相关问题