Java 实施彼得森';Eclipse不工作时互斥的s算法

Java 实施彼得森';Eclipse不工作时互斥的s算法,java,eclipse,algorithm,distributed-computing,mutual-exclusion,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, fal

我正在阅读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和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后,现在有两个变量同时进入临界区。如何修复它?

什么是
N
?你没有告诉我们你给了程序什么参数。另外,JavaScript不是Java,所以请不要使用“JavaScript片段”图标来输入Java代码。还有,什么是
Util.mySleep
?这可能会有很大的不同。好吧,我没有测试过这个,也没有尝试分析所有的代码,但是
while(wantCS[j]&&turn==j)看起来像个问题。首先,它可以进入一个无限循环,而不会让任何其他线程执行。当您在一个系统上运行多个线程时,要么正在运行的线程必须做一些允许其他线程运行的事情(这条语句没有),要么JVM必须实现某种时间切片,让一个线程运行一段时间,然后允许另一个线程运行。。。我不知道典型的JVM是否会这样做。。。。。。其次,即使另一个线程中断并更改了
turn
while
语句也可能没有注意到它,因为您没有将
turn
声明为
volatile
。如果它是易变的
,则代码确保每次使用时都读取它。如果没有,编译器可能会进行一些分析,并决定
turn
不可能更改,因此不必重新读取它。
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;
    }
}