使用java信号量作为两个Runnable类之间的锁



我有三个对象,它们是实现Runnable接口的两个不同类的实例。其中一个对象更改了另外两个对象的计数器,但我想确保整个更新操作不会被其他线程中断(即,我想为我的关键部分使用锁(。

在下面的代码中(这是实际代码的说明,而不是它本身(,我想确保关键部分的代码在没有任何中断的情况下执行。

我的一个想法是在Worker类中定义一个二进制信号量m,并用m.acquire()m.release()包围接触valueoperations的每个操作。但是,在"Runner"类中,我有一个对incrementValue()的调用,如果我用acquire()/release()调用包围CS,而我在incrementValue()中有同样的调用,那就没有意义了。

我有点困惑,我应该把信号量放在哪里,以实现相互排斥。

感谢

class Worker implements Runnable{
int value;
int operations;
// Semaphore m = new Semaphore(1);
...
...
void incrementValue(int n){
// m.acquire() here??
this.operations++;
this.value += n;
// m.release() here??
}
...
@Override
public void run(){
...
this.operations++;
this.value = getRandomNum(); 
...
}
}
class Runner implements Runnable {
Worker a, b;
...
...
@Override
public void run(){
...
// Start of the CS
// a.m.acquire() here?
// b.m.acquire() here?
a.incrementValue(x);
System.out.println("Value in WorkerA incremented by " + x);
b.incrementValue(y);
System.out.println("Value in WorkerB incremented by " + y);
// a.m.release() here?
// b.m.release() here?
// end of the CS
...
}
...
}

听起来您所面临的问题与ReentrantLock要解决的问题相同。ReentrantLock让你做到这一点:

final ReentrantLock m = new ReentrantLock();
void foo() {
m.lock();
doFooStuff();
m.unlock();
}
void bar() {
m.lock();
foo();
doAdditionalBarStuff();
m.unlock();
}

lock()调用检查调用线程是否已经拥有锁。如果调用方没有,那么它首先获取锁,必要时等待,最后在返回之前将count变量设置为1。

来自同一线程的后续lock()调用将看到线程已经拥有锁,并且它们将简单地递增计数器并返回。

unlock()调用递减计数器,并且只有当计数达到零时才释放锁。

最新更新