Dekker的3个过程算法(不起作用)

时间:2016-11-17 01:05:17

标签: java algorithm concurrency livelock

我正在尝试用Dekker的算法做一个简单的程序,但有3个进程。这是我的代码:

class DekkerAlg {

static final int iter = 2000000;
static volatile int sharedResource = 0;
/* Thread P wants to enter in the CS */
static volatile boolean wantp = false;
/* Thread Q wants to enter in the CS */  
static volatile boolean wantq = false;
/* Thread R wants to enter in the CS */  
static volatile boolean wantr = false;
/* Who's next? */
static volatile int turn = 1;

    class P extends Thread {
        public void run() {
            for (int i=0; i<iter; ++i) {
                wantp = true;
                while (wantq || wantr) {
                    if (turn == 2 || turn == 3) {
                        wantp = false;
                        while (turn == 2 || turn == 3)
                            Thread.yield();
                        wantp = true;
                    }
                }

                ++sharedResource;

                turn = 2;
                wantp = false;
            }
        }
    }

    class Q extends Thread {
        public void run() {
            for (int i=0; i<iter; ++i) {
                wantq = true;
                while (wantp || wantr) {
                    if (turn == 1 || turn == 3) {
                        wantq = false;
                        while (turn == 1 || turn == 3)
                            Thread.yield();
                        wantq = true;
                    }
                }

                --sharedResource;

                turn = 3;
                wantq = false;
            }
        }
    }

    class R extends Thread {
        public void run() {
            for (int i=0; i<iter; ++i) {
                wantr = true;
                while (wantp || wantq) {
                    if (turn == 1 || turn == 2) {
                        wantr = false;
                        while (turn == 1 || turn == 2)
                            Thread.yield();
                        wantr = true;
                    }
                }

                ++sharedResource;

                turn = 1;
                wantr = false;
            }
        }
    }

    DekkerAlg() {
        Thread p = new P();
        Thread q = new Q();
        Thread r = new R();
        p.start();
        q.start();
        r.start();

        try {
            p.join();
            q.join();
            r.join();
            System.out.println("Shared Resource value: " + sharedResource);
            System.out.println("Should be 2000000.");
        }
        catch (InterruptedException e) {}
    }

    public static void main(String[] args) {
        new DekkerAlg();
    }
}

我不知道我的代码是否100%正确。如果P想要进入CS,首先,他必须检查Q或R是否也想进入,如果轮到他,他等待。与线程Q和R相同的过程。

  • 2000000次迭代:程序不起作用
  • 200次迭代:程序有时会工作

我猜Dekker的算法不适用于3个进程,但我需要知道我的代码是否正确以及我的程序失败的原因。

感谢。

1 个答案:

答案 0 :(得分:0)

当试图了解算法的任何给定实现是否有效时,可以推理它(“证明”正确性)或测试它。
通过实施,QP的ID分配给turn,不要(实例化,启动和)加入R
重构时只使用一个可运行类的实例:volatile type []声明对类型数组的易变引用 - 你还需要别的东西。

如果有两个以上的流程,您的扩展程序会使流程挨饿,而不会将turn设置为永远不会将turn设置为任何其他值的流程的ID(已完成或已完成)终止),以及任何其他进程既未完成也未终止。

困难的部分将是mutual exclusion for 3 processes […] without [changing Dekker's] entire algorithm - 您可能会发现自己正在追溯MutEx实施的历史 早期版本的内存模型与JVM Memory Model大不相同。