2014-12-02 2 views
0

У меня есть поток производителей, который будет продолжать вставлять значения в связанныйBlockingQueue и иметь несколько потоков потребителей, которые будут принимать() из этого связанногоBlockingQueue одновременно. Мое условие, чтобы они продолжали думать, это когда мой флаг для продюсера закончен, это ложь, и они перестанут пытаться принять, когда это правда. однако я столкнулся с проблемой, по которой мой второй поток находится в блочном процессе take(). Я считаю, что это связано с тем, что до того, как мой производитель установил флаг в true, когда он закончится, один из протекторов уже находится внутри тела run(), выполняющего метод блокировки take(). Поскольку в связаннуюBlockingQueue не будет добавлен какой-либо новый элемент, он будет навсегда блокировать процессы. Как я могу исправить эту проблему?Как возобновить мой поток, который находится в процессе блокировки из-за связанногоBlockingQueue.take()

ответ

2

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

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

+0

Не могли бы вы помочь мне подумать о каком-то значении яда, которое, возможно, является именем файла, и как я могу выйти из метода run()? – 10e5x

+0

Спасибо, я продолжаю цикл while, а затем вырывается из него. Однако мое значение яда - «endOfWorkQueue», не думаю, что это уникальное значение enuff для fileName ... все еще существует возможность, когда ppl будет вводить это как имя файла – 10e5x

+0

Чтобы выйти из запуска, просто вызовите return. Для имени файла проверьте это: http://stackoverflow.com/questions/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names. В Windows имя файла не может содержать: \ /:? * <> | – javaHunter

0

Вы можете прервать поток, который ждет на take(), поэтому take() будет вызывать InterruptedException, которое поймано, поэтому выполнение переходит в предложение catch.

+0

Как прервать поток, который находится в процессе блокировки? – 10e5x