Чтение API для CountdownLatch заставляет меня задуматься, можете ли вы использовать его так, как вы пытаетесь его использовать.
"Средство синхронизации, позволяющее одному или нескольким потокам дождаться завершения набора операций, выполняемых в других потоках."
Метод run в примере CountdownLatch выглядит следующим образом:
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
Он ожидает сигнала запуска, но не выполняет countDown, пока не завершится его метод работы. Похоже, вы неправильно используете CountdowLatch, и его реальная цель - убедиться, что все потоки завершены до того, как основной поток может завершиться.
Итак, вот мое предложение: запускать каждый поток, как вы, но вместо использования CountdownLatch, каждый цикл цикла должен быть статическим логическим значением, пока значение не изменится на false. Таким образом, вы запускаете все потоки, затем вы можете установить для ThreadLocal значение false, и все они должны вызывать play (). Обратите внимание, что это, вероятно, не код производственного качества, и вам действительно нужно, чтобы каждый поток прослушивал событие, но попытайтесь.
Общая проблема может заключаться в том, что виноваты в планировании потоков ОС, и именно в этом разработчики JPlayer 1.0 придумали решение, но если аппаратное и операционное взаимодействие взаимодействуют, оно должно быть в состоянии добиться успеха. () происходит одновременно для каждого потока плюс или минус пара миллисекунд.
Последнее редактирование: чем больше я смотрю на CountdownLatch, тем больше я думаю, что вы можете использовать его для синхронизации запуска потоков. Вы не хотите обратного отсчета в каждой теме, вы просто хотите:
startSignal.await();
play();