Lambda 表达式可以解决死锁吗?
Can a Lambda expression resolve deadlock?
我目前正在研究 Java Deadlock Tutorial 并且了解程序示例总是会遇到死锁。
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 表达式替换其中一个 Thread 实例时:new Thread(() -> gaston.bow(alphonse)).start();
它似乎解决了死锁问题。但是当两个 Thread 实例化都被 lambdas 替换时,程序再次陷入僵局。
这背后有什么原因吗?
测试中有一场比赛。它只会在两个线程同时 bow
时死锁。
输出%s: %s has bowed to me!
字符串所花费的时间足以在第一种情况下导致死锁,但在引入实例化lambda class的额外时间时不会。
通过在 bow
中引入延迟,可以在使用 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();
}
我目前正在研究 Java Deadlock Tutorial 并且了解程序示例总是会遇到死锁。
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 表达式替换其中一个 Thread 实例时:new Thread(() -> gaston.bow(alphonse)).start();
它似乎解决了死锁问题。但是当两个 Thread 实例化都被 lambdas 替换时,程序再次陷入僵局。
这背后有什么原因吗?
测试中有一场比赛。它只会在两个线程同时 bow
时死锁。
输出%s: %s has bowed to me!
字符串所花费的时间足以在第一种情况下导致死锁,但在引入实例化lambda class的额外时间时不会。
通过在 bow
中引入延迟,可以在使用 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();
}