在Eclipse中实现彼得森的互斥算法不起作用

时间:2017-05-09 03:37:05

标签: java eclipse algorithm distributed-computing mutual-exclusion

我正在阅读 Vijay K. Garg 中的 Java并行和分布式计算这本书,并且我对Peterson的算法存在一些问题。

锁定界面:

public interface Lock {
    public void requestCS(int pid);
    public void releaseCS(int pid);
}
彼得森的算法:

public class PetersonAlgorithm implements Lock {

    boolean wantCS[] = {false, false};
    int turn = 1;

    @Override
    public void requestCS(int i) {
        int j = 1 - i;
        wantCS[i] = true;
        turn = j;
        while (wantCS[j] && turn == j) ;
    }

    @Override
    public void releaseCS(int i) {
        // TODO Auto-generated method stub
        wantCS[i] = false;
    }
}

这两个类应该没问题,但是当我在Eclipse上用代码

测试它时
import java.util.Random;

public class TestMutualExclusive extends Thread {

    int myId;
    Lock lock;
    Random r = new Random();

    public TestMutualExclusive(int id, Lock lock) {
        myId = id;
        this.lock = lock;
    }

    void nonCriticalSection() {
        System.out.println(myId + " is not in CS");
        Util.mySleep(r.nextInt(1000));
    }

    void CriticalSection() {
        System.out.println(myId + " is in CS ****");
        Util.mySleep(r.nextInt(1000));
    }

    public void run() {
        while (true) {
            lock.requestCS(myId);
            CriticalSection();
            lock.releaseCS(myId);
            nonCriticalSection();
        }
    }

    public static void main(String[] args) throws Exception {
        int N = Integer.parseInt(args[0]);
        TestMutualExclusive t[] = new TestMutualExclusive[N];
        Lock lock = new PetersonAlgorithm();
        for (int i = 0; i < N; i++) {
            t[i] = new TestMutualExclusive(i, lock);
            t[i].start();
        }
    }
}

唯一出来的是

0 is in CS ****
0 is not in CS

而不是0和1交替进入临界区。有什么问题?

UPD1:N是我想要运行的线程数
UPD2:显然如果我添加mySleep功能它可以工作,但我仍然不知道为什么。

public class PetersonAlgorithm implements Lock {

    boolean wantCS[] = {false, false};
    int turn = 1;

    @Override
    public void requestCS(int i) {
        int j = 1 - i;
        wantCS[i] = true;
        turn = j;
        while (wantCS[j] && turn == j) Util.mySleep(100);
    }

    @Override
    public void releaseCS(int i) {
        // TODO Auto-generated method stub
        wantCS[i] = false;
    }
}

UPD3:mySleep是一个以时间作为参数来停止线程的函数。

UPD4:问题是turn变量不易变。将其设置为volatile后,现在它有两个变量一次进入临界区。我该如何解决?

0 个答案:

没有答案