Java 实施彼得森';Eclipse不工作时互斥的s算法
我正在阅读Vijay K.Garg的《Java并发和分布式计算》一书,我对Peterson的算法有一些疑问 锁定接口: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
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;
}
}