互斥代码

时间:2013-02-10 23:24:42

标签: java multithreading

我正在尝试将此代码转换为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);
    }
}  

我知道我的代码有一些错误。谢谢你的帮助!

1 个答案:

答案 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()

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#incrementAndGet()

您可能会注意到这会增加它,但它不会使其模数为n。好吧,无论何时读取它的值,你都可以将它取模,你不需要以那种方式存储它。

编辑:顺便说一下,做这样的事情:

while (turn != i);

被称为忙等待,这是一个坏主意,因为它意味着CPU使用率将是100%,每秒检查变量数十万次。在这种情况下,不是让每个线程尽可能频繁地进行检查,而是希望线程wait在另一个线程被notify编辑时,该线程将继续执行。

我相信Java使用locksynchronized实现互斥也会为您提供此属性,例如:如果您尝试锁定某些内容或进入同步块但它已经在使用中,那么该线程将进入休眠状态并在轮到它时被唤醒。所以,你也可以研究一下。