0

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

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

4

1 回答 1

4

使用AtomicInteger.

原子意味着在任何其他线程可以看到结果之前对其进行的任何操作都将完全完成。这意味着您不会有两个同时操作“破坏”它。例如,假设您有一个非原子整数,并且两个线程试图同时递增它——假设它的值为 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实现互斥也会给你这个属性,例如,如果你尝试锁定某个东西或进入一个同步块但它已经在使用中,那么线程进入睡眠状态并在它被唤醒时被唤醒轮到它了。所以,你也可以调查一下。

于 2013-02-10T23:31:14.837 回答