Я думаю, вы не можете сделать это без специального синхронизатора. Я взломал это, я назвал его TrafficLight
, так как он пропускает потоки с определенным состоянием, останавливая других, пока он не изменит состояние:
public class TrafficLight<T> {
private final int maxSequence;
private final ReentrantLock lock = new ReentrantLock(true);
private final Condition allClear = lock.newCondition();
private int registered;
private int leftInSequence;
private T openState;
public TrafficLight(int maxSequence) {
this.maxSequence = maxSequence;
}
public void acquire(T state) throws InterruptedException {
lock.lock();
try {
while ((this.openState != null && !this.openState.equals(state)) || leftInSequence == maxSequence) {
allClear.await();
}
if (this.openState == null) {
this.openState = state;
}
registered++;
leftInSequence++;
} finally {
lock.unlock();
}
}
public void release() {
lock.lock();
try {
registered--;
if (registered == 0) {
openState = null;
leftInSequence = 0;
allClear.signalAll();
}
} finally {
lock.unlock();
}
}
}
acquire()
будет блокироваться, если другое состояние активен, пока он не станет неактивным.
maxSequence
помогает предотвратить потоковое голодание, позволяя передавать только максимальное количество потоков (тогда они должны будут стоять так же, как и остальные) , Вы можете сделать вариант, который использует временное окно.
Для вашей проблемы someMethod1()
и someMethod2()
вызовет метод получения () с другим состоянием в начале и release()
в конце .