gpt4 book ai didi

java - 请帮助我理解这个死锁示例

转载 作者:行者123 更新时间:2023-12-01 16:51:27 25 4
gpt4 key购买 nike

在我的编程语言类(class)中,我们得到了一个简单的 Java 死锁示例,并被要求解决它。我并不是直接想要这个问题的答案,我主要是想知道我的理解哪里还欠缺。代码如下:

import java.applet.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

// Attempt at a simple handshake. Girl pings Boy, gets confirmation.
// Then Boy pings girl, get confirmation.
class Monitor {
String name;

public Monitor (String name) { this.name = name; }

public String getName() { return this.name; }

// Girl thread invokes ping, asks Boy to confirm. But Boy invokes ping,
// and asks Girl to confirm. Neither Boy nor Girl can give time to their
// confirm call because they are stuck in ping. Hence the handshake
// cannot be completed.
public synchronized void ping (Monitor p) {
System.out.println(this.name + " (ping): pinging " + p.getName());
p.confirm(this);
System.out.println(this.name + " (ping): got confirmation");
}

public synchronized void confirm (Monitor p) {
System.out.println(this.name+" (confirm): confirm to "+p.getName());
}
}

class Runner extends Thread {
Monitor m1, m2;

public Runner (Monitor m1, Monitor m2) {
this.m1 = m1;
this.m2 = m2;
}

public void run () {
//System.out.println(m1.getName() + " about to ping " + m2.getName());
m1.ping(m2);
}
}

public class DeadLock {
public static void main (String args[]) {
int i=1;
System.out.println("Starting..."+(i++));
Monitor a = new Monitor("Girl");
Monitor b = new Monitor("Boy");
(new Runner(a, b)).start();
(new Runner(b, a)).start();
}
}

当我执行上面的代码时,我相信每次都会发生以下情况(尽管事实并非如此,因为有时我们会陷入僵局):

女孩 ping 男孩,在 ping() 方法上加锁。 Girl 在 ping() 内尝试调用 boy.confirm()。 Boy 的 confirm() 回答,从而将我们带回 Girl.ping() ,并在此处结束,解除 ping() 的锁定,而 Boy 的实例执行完全相同的操作。有了所有的锁,似乎整个程序都是序列化的,但这违背了多线程的目的?无论如何,我通常会得到以下输出

Starting...1
Girl (ping): pinging Boy
Boy (confirm): confirm to Girl
Girl (ping): got confirmation
Boy (ping): pinging Girl
Girl (confirm): confirm to Boy
Boy (ping): got confirmation

但是有时我们会遇到死锁,输出变成:

Girl (ping): pinging Boy
Boy (ping): pinging Girl

我不明白我们如何进入这种状态,因为当我们第一次进入时,我们似乎锁定了 ping() 方法,所以 Boy 怎么可能调用 ping() 如果女孩已经在使用它了?当男孩正忙于调用ping()时,女孩是否正在尝试调用boy.confirm()

最佳答案

您的 ping 方法已同步并锁定 this,然后继续对 p 调用 confirm >,因此也尝试获取其锁定。步骤:

  1. “Girl”线程获取 Boy 对象上的锁,进入 ping
  2. “Boy”线程获取 Girl 对象的锁,进入 ping
  3. Girl想要调用Boy.confirm,等待锁;
  4. Boy想要调用Girl.confirm,等待锁;
  5. 陷入僵局。

关于java - 请帮助我理解这个死锁示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39363062/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com