Привет, у меня есть ситуация, в которой я должен разрешить только одному потоку сказать обновить переменную.
Существует триггер, который может вызывать несколько потоков для обновления этой переменной, однако обновление должно происходить только один раз первым потоком, который достигнет критической секции.
В идеале поток должен быть следующим:
Thread-1;Thread-2 и Thread-3 вызываются для обновления переменной в критической секции, защищенной блокировкой или мьютексом
Критическая секция с использованием этой защиты позволяет входить только одному потоку, Thread-2 и Thread-3 просто ждутснаружи.
Как только эта переменная обновлена Thread-1;Thread-2 и Thread-3 возобновляют работу, не влияя на переменную.
Я предложил следующую реализацию, но я не могу заставить другие потоки ждать и пропустить обновление:
public class Main {
private static ReentrantLock lock = new ReentrantLock();
private int counter = 0;
public static void main(String[] args) {
Main m = new Main();
new Thread(m::doSomeOperation).start();
new Thread(m::doSomeOperation).start();
new Thread(m::doSomeOperation).start();
}
private void doSomeOperation() {
try {
System.out.println("Thread about to acquire lock: " + Thread.currentThread().getName());
if (lock.tryLock()) {
System.out.println("Lock held by " + Thread.currentThread().getName() + " " + lock.isHeldByCurrentThread());
counter++;
// Thread.sleep(3000);
System.out.println("Counter value: " + counter + " worked by thread " + Thread.currentThread().getName());
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
System.out.println("Unlocked: " + Thread.currentThread().getName());
}
}
}
}
В конце значение счетчика равно 3, я хочузначение счетчика равно единице, и я хочу, чтобы другие потоки подождали, пока первый поток обновит счетчик. Идеи приветствуются. Я бы предпочел решение, использующее блокировки / мьютекс, а не ждать и уведомлять.
Вывод:
Thread about to acquire lock: Thread-0
Lock held by Thread-0 true
Thread about to acquire lock: Thread-1
Counter value: 1 worked by thread Thread-0
Unlocked: Thread-0
Thread about to acquire lock: Thread-2
Lock held by Thread-2 true
Counter value: 2 worked by thread Thread-2
Unlocked: Thread-2
Process finished with exit code 0
Примечание Мой вариант использования отличается - пример обновления счетчика приведен для простоты. На самом деле я обновляю токен сеанса в методе doSomeOperation.