我正在阅读 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后,现在它有两个变量一次进入临界区。我该如何解决?