Java - Dekkers算法实现导致临界区中的两个线程

问题描述 投票:0回答:1

我试图在有两条铁路的场景中实施Dekkers算法,并且有一个点它们都使用轨道的相同部分。只允许一列火车一次进入这个区域,一列火车可以连续多次通过,除非它是其他火车转弯并准备通过。

以下是我为第一条铁轨实施的代码。

while (allowed) {
        choochoo();
        setWantToUseTrack(0,true);
        while (getWantToUseTrack(1)) {
            if (getTurn() != 0) {
                setWantToUseTrack(0,false);
                while (getTurn() != 0) {
                    //wait loop
                }
                setWantToUseTrack(0, true);
            }
        }
        //critical section starts
        crossPass();
        //critical section ends
        setTurn(1);
        setWantToUseTrack(0,false);
    }
}

以下是我实施第二条铁轨的代码。

while (allowed) {
        choochoo();
        setWantToUseTrack(1,true);
        while (getWantToUseTrack(0)) {
            if (getTurn() != 1) {
                setWantToUseTrack(1,false);
                while (getTurn() != 1) {
                    //wait loop
                }
                setWantToUseTrack(1,true);
            }
        }
        //critical section starts
        crossPass();
        //critical section ends
        setTurn(0);
        setWantToUseTrack(1,false);
    }

当此代码运行时,有时两列列车同时在关键部分结束。我看不出逻辑错误。我错过了我的实施内容吗?

java multithreading algorithm java-threads
1个回答
1
投票

有可能发生以下情况(只是一个例子):

  1. 在第二轨道中调用setWantToUseTrack(1,false);
  2. 在第一个轨道谓词被检查:while (getWantToUseTrack(1)),第二个线程没有在while循环中停止。 这绝对是可行的,因为choochoo();可以阻止第一个音轨直到(1.)和第二个音轨直到(2.)发生。
  3. 方法getWantToUseTrack返回false为0和1。

创建一个循环来捕获线程直到释放临界区是有点危险的。您可能希望通过使用带有synchronized定义的crossPass来使该节具有线程安全性。

© www.soinside.com 2019 - 2024. All rights reserved.