Подтвердить что ты не робот

Есть ли способ дождаться изменения атомного целого

Есть ли способ подождать AtomicInteger, чтобы мне не пришлось спать мой текущий поток и продолжать проверять AtomicInteger, как этот

while(atomicInt.get() >= 0) {
    Thread.sleep(1000)
}

Я знаю, что есть такая вещь, как CountDownLatch, но это только позволяет мне уменьшаться. Мне также нужно, чтобы он мог увеличивать

Далее BackStory - У меня есть цикл, создающий потоки, и мне нужно дождаться завершения одного из потоков, прежде чем создавать новый поток. Тем не менее, я использую Executors.newFixedThreadPool(numThreads), и единственный способ подождать, похоже, заключается в том, чтобы вызвать метод shutdown wait end, а затем создать новый threadPool, поэтому вместо этого я использовал атомное целое, чтобы отслеживать, сколько потоков было запущено, и/или в очереди, чтобы при уменьшении этого числа я мог продолжить цикл.

4b9b3361

Ответ 1

Semaphore похоже, что он может быть ближе к тому, что вы ищете, на самом деле - он позволяет подождать, пока один или несколько "Разрешения" доступны. AtomicInteger не предназначен для использования, как вы его используете.

Ответ 2

Я думаю, что вы действительно хотите обработать какое-то событие. Это событие может, в свою очередь, увеличивать целое число. Взгляните на BlockingQueue.

Очередь, которая дополнительно поддерживает операции, которые ждут, когда очередь становится непустой при извлечении элемента, и подождите, пока пространство станет доступным в очереди при хранении элемента.

Код может выглядеть примерно так:

MyEvent incrementEvent = queue.take(); //blocks until an event is added to the queue
// increment int and do logic here

Ответ 3

Я думаю, что более близкое совпадение с тем, что вам нужно, это Phaser. Мое грубое понимание заключается в том, что оно немного похоже на счетчик приращений, где вы можете блокировать до тех пор, пока номер не будет увеличен.

// This constructor one party (so it expects one advance per phase).
Phaser phaser = new Phaser(1);
try {
  // This will timeout as phase 0 hasn't arrived yet.
  phaser.awaitAdvanceInterruptibly(0, 1, TimeUnit.MILLISECONDS);
  fail();
}
catch (TimeoutException expected) {
}

// Arrive phase 0
phaser.arrive();
phaser.awaitAdvance(0);
try {
  // Phase 1 will timeout..
  phaser.awaitAdvanceInterruptibly(1, 1, TimeUnit.MILLISECONDS);
  fail();
}
catch (TimeoutException expected) {
}

// Arrive phase 1
phaser.arrive();
phaser.awaitAdvance(0);
phaser.awaitAdvance(1);

Ответ 4

Если вы используете API-интерфейс Executors, правильный способ дождаться завершения задачи - использовать API будущего. Пример кода показан ниже:

Future<?> future = threadPool.submit(task);
future.get();

Ответ 5

Простое решение с CompletableFuture

Создать CompletableFuture, доступный для обоих потоков thread1, thread2

private CompletableFuture<Integer> future = new CompletableFuture<>();

Ожидание значения в потоке 1 (или в нескольких потоках)

Integer value = future.join();

Рассчитать стоимость в thread2 и завершить будущее

if (!future.isDone()) future.complete(calculatedValue);