Подождите, пока все потоки не ждут, прежде чем уведомить - PullRequest
0 голосов
/ 12 ноября 2018

В MyClass Я создаю несколько потоков в цикле следующим образом:

for(int i = 0; i < 4; i++)
{
    threads[i] = new Thread(new MyRunnable(lock));
    threads[i].start();
}

где lock является свойством MyClass, и каждый из этих потоков в своем методе run вызывает lock.wait().

После того, как я создал эти потоки, я хочу назначить одному из них управление блокировкой. Я попытался просто поставить lock.notify() после цикла, но он запускается слишком быстро - хотя после цикла ни один из потоков еще не выполнил lock.wait(), поэтому все они пропускают lock.notify(), а затем бесконечно ждут другого это никогда не приходит.

Я могу немного остановить выполнение основного потока, например, выполнить Thread.sleep(1000), прежде чем я позвоню lock.notify(). Это работает, поскольку дает нитям возможность добраться до стадии wait ing до notify ing. Но это не выглядит очень элегантно, и, очевидно, я бы предпочел не останавливать основное выполнение моей программы, как это.

Как мне этого добиться?

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Взгляните на метод Thread.join(), который может помочь вам заставить текущий поток ждать, пока поток, вызвавший этот метод, не будет завершен.

Пример:

Thread t1 = new Thread();
Thread t2 = new Thread();
t1.start();
t1.join();
t2.start();

Здесь t2 будет ожидать завершения t1.Подробнее об этом вы можете прочитать здесь .

0 голосов
/ 12 ноября 2018

Вы можете использовать еще несколько высокоуровневых конструкций из пакета параллелизма, таких как Семафор .

Таким образом, вы должны настроить Семафор с одним «разрешением» перед вашимцикл, передать его в ваши потоки, и тогда все они будут пытаться «приобрести» это разрешение (что может сделать только один из них, другие потерпят неудачу).

Даже Семафор довольно низокна уровне, обычно вы можете найти что-то еще более приспособленное к вашему реальному приложению, например, блокирование очередей или одновременных коллекций.

...