У меня есть три объекта, которые являются экземплярами двух разных классов, реализующих интерфейс Runnable
. Один из объектов изменяет счетчики двух других объектов, но я хочу убедиться, что вся операция обновления не прерывается другими потоками (т. Е. Я хочу использовать блокировку для своего критического раздела).
В код ниже (это иллюстрация реального кода, а не самого), я хочу убедиться, что код в критическом разделе выполняется без каких-либо перерывов.
Одна мысль, которая у меня возникла, - определить двоичный семафор m в классе Worker
и окружить каждую операцию, которая касается value
и operations
, m.acquire()
, за которой следует m.release()
. Но в классе 'Runner' у меня есть вызов на incrementValue()
, и если я окружаю CS вызовами acquire()/release()
, в то время как у меня то же самое в 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
...
}
...
}