2017-09-19 60 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使用拉姆达通过引入延迟时进行测试僵局