此Java程序不显示预期的死锁

时间:2017-12-15 10:31:29

标签: java multithreading synchronization

根据Oracle java文档(https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html)中给出的死锁示例,我想模拟我国的情况。当一对列车在相反的方向上行驶时,到达中间站的列车首先给等候的工作人员一个“钥匙”(列车没有停下来,但是发动机司机向平台扔了一个带钥匙的大袋子。在那里等待的工作人员将收集它)。然后由另一列火车收集,然后到达中间站。如果两列火车同时到达火车站,则会导致死锁。所以,我编写了以下代码来说明这一点:

public class Deadlock
{
    static class Express
    {
        private final String name;
        public Express(String name)
        {
            this.name = name;
        }
        public String getName()
        {
            return this.name;
        }
        public synchronized void reached(Express laterTrain)
        {
            System.out.println(this.name + " is earlier than " +
                laterTrain.getName());
            giveKey(laterTrain);
        }
        public synchronized void giveKey(Express laterTrain)
        {
            System.out.println(name + " gives key to " +
                laterTrain.getName());
        }
    }
   public static void main(String[] args)
    {
        final Express Rajdhani1 = new Express("Rajdhani ONE");
        final Express Rajdhani2 = new Express("Rajdhani TWO");
        new Thread(new Runnable()
        {
            public void run()
            {
                Rajdhani1.reached(Rajdhani2);
            }
        }).start();
        new Thread(new Runnable()
        {
            public void run()
            {
                Rajdhani2.reached(Rajdhani1);
            }
        }).start();
    }
}

我期待输出如下:

Rajdhani ONE is earlier than Rajdhani TWO
Rajdhani TWO is earlier than Rajdhani ONE

并且程序永远挂在那里。但是,我得到了以下输出,执行迅速返回到命令行。怎么样?

Rajdhani ONE is earlier than Rajdhani TWO
Rajdhani TWO is earlier than Rajdhani ONE
Rajdhani ONE gives key to Rajdhani TWO
Rajdhani TWO gives key to Rajdhani ONE

2 个答案:

答案 0 :(得分:1)

我没有运行您的代码,但您的处理方式与链接的示例代码不同:您在giveKey函数中的错误对象上调用reached()

根据引用的例子,它应该是:

// bower.bowBack(this);
laterTrain.giveKey(this);

但你在打电话:

// this.bowBack(bower);
this.giveKey(laterTrain);

答案 1 :(得分:0)

当您调用giveKey方法时,您将不同的对象传递给该方法。难道你不能传递调用该​​方法的对象吗?

你应该通过"这个" toKey函数并检查输出。它应该按照您提供的文档链接工作。