2017-09-19 66 views
2

我目前正在通過Java Deadlock Tutorial工作並瞭解程序示例總是會遇到死鎖。Lambda表達式是否可以解決死鎖問題?

public class Deadlock 
    { 
     private static class Friend 
     { 
      private final String name; 
      public Friend(String name) { this.name = name; } 

      public String getName() {return 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(){ 
       @Override 
       public void run() 
       { 
        alphonse.bow(gaston); 
       } 
      }).start(); 

      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        gaston.bow(alphonse); 
       } 
      }).start(); 

     } 
    } 

當我更換一個合適的lambda表達式線程實例之一:new Thread(() -> gaston.bow(alphonse)).start(); 這似乎解決死鎖問題。但是當兩個線程實例化都被lambdas替換時,程序又會死鎖。

背後有一個原因嗎?

回答

1

測試中有一場比賽。如果兩個線程bow在同一時間只會死鎖。

輸出%s: %s has bowed to me!字符串所花費的時間足以導致第一種情況下的死鎖,但不會引入實例化lambda類的額外時間。通過在開始測試前將其實例化

public synchronized void bow(Friend bower) 
{ 
    System.out.format("%s %s: %s has bowed to me!%n", System.currentTimeMillis(), this.name, bower.getName()); 
    try { 
     Thread.sleep(50); 
    } catch (InterruptedException e) { 
     // ignore 
    } 
    bower.bowBack(this); 
} 

...或:

public static void main(String[]args) throws InterruptedException { 
    final Friend alphonse = new Friend("alphonse"); 
    final Friend gaston = new Friend("gaston"); 

    // instantiate the runner early 
    Runnable gastonRunner =() -> gaston.bow(alphonse); 

    new Thread(new Runnable(){ 
     @Override 
     public void run() 
     { 
      alphonse.bow(gaston); 
     } 
    }).start(); 


    new Thread(gastonRunner).start(); 
} 

您可以bow使用拉姆達通過引入延遲時進行測試僵局