Я пытаюсь запустить список потоков из main, где один из них, назовем его tLast, должен запускаться индивидуально после того, как остальные перешли в состояние ожидания. Я знаю о t.join, но, насколько я понимаю, он работает, только если поток завершает свою работу, и, как я понимаю, ожидание не считается. Пока что я попробовал это, запустив все потоки, кроме tLast:

boolean inSleepState = false;
while(!inSleepState){
    inSleepState = true;
    for(Thread thread: threads){
        if(thread.checkState != Thread.state.WAITING){
            inSleepState = false; 
            break;
        }
    }
}

tLast.start()

Главная проблема, которую я вижу в этом, заключается в том, что это напряженное ожидание, что является плохой практикой и, насколько я знаю, плохим советом, но я не могу придумать другого способа сделать это. Кстати, я понимаю, что могу ждать каждого потока по отдельности и сэкономить итерацию в течение threads, но в любом случае это занятое ожидание.

0
Roee Weiss Lipshitz 21 Дек 2019 в 05:35

1 ответ

Лучший ответ

Метод join присоединится к потоку только после его завершения. Поток в состоянии ОЖИДАНИЯ не прерывается.

Таким образом, прямой ответ заключается в том, что вы не можете присоединиться к ожидающей ветке.

Но с другой стороны, Thread::join не делает занятого ожидания.

Третье, на что следует обратить внимание, это то, что полагаться на состояние потока для обозначения чего-либо довольно грубо. Если поток находится в состоянии WAITING, это говорит о том, что он ожидает notify в некотором мьютексе. Он не говорит вам, какой мьютекс он использует.

Теперь ... предположительно ... вы хотите, чтобы ваш поток tLast проснулся, когда другие потоки достигнут определенного состояния. Если это то, чего вы пытаетесь достичь, вам могут понадобиться CountdownLatch, Semaphore или CyclicBarrier.

1
Stephen C 21 Дек 2019 в 15:40