我正在尝试将此代码转换为java并使用线程来实现它
turn = 0 // shared control variable
while (turn != i);
// CS
turn = (turn + 1) % n;
我真的很努力地找到正确的代码,但我失败了,这是我的代码
/*
* Mutual exclusion using thread
*/
class gV{
int turn=0;
}
class newThread extends Thread{
static int i;
int n=10;
newThread(gV obj){
this.i=obj.turn;
start();
}
public void run(){
while(obj.turn!=i&&obj.turn<n);
criticalSection(i);
obj.turn=(obj.turn+1);
i++;
}
public void criticalSection(int numOfProcess){
System.out.println("Process " + numOfProcess + " done!!");
}
}
class MutualExclusion{
public static void main(String args[]){
gV obj = new gV();
new newThread(obj);
}
}
我知道我的代码有一些错误。谢谢你的帮助!
答案 0 :(得分:4)
使用AtomicInteger
。
Atomic意味着在任何其他线程可以看到结果之前,它上面的任何操作都将完全完成。这意味着你不会有两个同时操作'clobber'它。例如,想象一下如果你有一个非原子整数并且两个线程试图同时递增它 - 比如它的值为1,它们都将它读为1并尝试将其设置为2.它们都将它递增一次 - 但不是它变成3,变成2! AtomicInteger
通过提供IncrementAndGet
解决了这个问题,它保证在增量完成之前没有其他线程可以访问AtomicInteger
的值。
特别是,请使用以下方法:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#get()
您可能会注意到这会增加它,但它不会使其模数为n。好吧,无论何时读取它的值,你都可以将它取模,你不需要以那种方式存储它。
编辑:顺便说一下,做这样的事情:while (turn != i);
被称为忙等待,这是一个坏主意,因为它意味着CPU使用率将是100%,每秒检查变量数十万次。在这种情况下,不是让每个线程尽可能频繁地进行检查,而是希望线程wait
在另一个线程被notify
编辑时,该线程将继续执行。
我相信Java使用lock
和synchronized
实现互斥也会为您提供此属性,例如:如果您尝试锁定某些内容或进入同步块但它已经在使用中,那么该线程将进入休眠状态并在轮到它时被唤醒。所以,你也可以研究一下。