Если я правильно понимаю, есть N задач, которые нужно выполнить, когда подается тиковый сигнал. N -я задача может начаться только после завершения первых N-1 задач.Поскольку функция notifyAll () уведомляет потоки неупорядоченным образом, вам необходимо немного расширить свой код.
Прежде всего, я думаю, что эта конструкция не является безопасной конструкцией.Подумайте о том, что выполнение кода в потоке занимает больше 1 секунды.В этом случае поток не будет уведомлен при следующем сигнале тика, так как он еще не достиг функции wait ().Однако на данный момент давайте предположим, что этого не произойдет.
Поскольку N -я задача может быть выполнена только после завершения первых N-1 задач., он должен ждать и должен быть уведомлен, когда первые задачи N-1 фактически завершены.Для подсчета количества выполненных задач вы можете использовать потокобезопасный счетчик AtomicInteger.Каждый раз, когда задача завершается, счетчик увеличивается на 1. Когда счетчик достигает значения N-1 , он уведомляет N -й поток и значение сбрасывается на 0.
Чтобы дать вам код:
// Besides a tickSignal, we also need a finalThreadSignal, which
// will be notified when the first N-1 Threads are finished.
private Object tickSignal = new Object();
private Object finalThreadSignal = new Object();
private AtomicInteger completedThreadsCounter = new AtomicInteger(0);
Резьба 1- (N-1):
while (running) {
synchronized (tickSignal) {
try {
tickSignal.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Code
// Task finished
int counter = completedThreadsCounter.incrementAndGet();
if (counter == N-1) {
// Notify Thread N when the first N-1 tasks are finished
synchronized (finalThreadSignal) {
finalThreadSignal.notify();
}
// Reset the finished Threads counter and wait for the next tick signal
completedThreadsCounter.set(0);
}
}
}
Резьба N:
while (running) {
// Here we synchronize on the signal that will be given when
// the first N-1 Threads are finished
synchronized (finalThreadSignal) {
try {
finalThreadSignal.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Execute final Thread code
}
}
Как я уже указывал, эта конструкция потерпит неудачу, если время выполнения в потоке больше, чем время между двумя тиками.Пожалуйста, дайте мне точно знать, в чем проблема, чтобы дать вам более подходящий ответ.