2012-06-13 2 views
1

У меня есть класс A со свойством LinkedBlockingQueue. В одном методе A я вызываю метод LinkedBlockingQueue.put(), так как я хочу вставить элемент в очередь. Но, если очередь заполнена, мой поток будет ждать, пока не будет доступно пространство, или пока мой поток не будет прерван.Блокировка очереди и InterruptedException

Проблема в том, что даже если мой поток прерывается, я хочу, чтобы элемент находился в очереди.

Есть ли способ удостовериться, что мой элемент был вставлен в очередь?

Благодаря

ответ

2

Единственный способ, по которому я вижу, - вызвать queue.put() в цикле. Этот путь может быть

boolean added = false; 

while (!added){ 
    try{ 
     queue.put(value); 
     added = true; 
    }catch(InterruptedException ie){ 
     // do something if required 

     // make sure to set the interrupted flag on the thread, since it was cleared 
     // when the exception was thrown 
     Thread.currentThread().interrupt(); 
    } 
} 

if(Thread.currentThread.isInterrupted()){ 
    // you were previously interrupted before, so try to exit gracefully 
    return; 
} 
+0

Какова цель заявления IF? –

+0

Ну, если ваш поток был прерван, правильное поведение - попытаться остановить этот поток как можно раньше (это то, что прерывает поток). Вы не хотите, чтобы ваш поток вышел, прежде чем вы убедитесь, что элемент находится в очереди, но вы также должны уважать значение прерванного Exception, которое вы ранее получили. Это может быть не актуально в вашем случае, но это то, что используется в последнем случае if. – LordOfThePigs

+0

При каких обстоятельствах поток, который был прерван, должен выйти? Почему, по вашему мнению, мы должны понимать из исключения, что что-то «идет не так» и что нам нужно подготовить закрытие потока? –

3

Вы должны решить, хотите ли вы ждать, если очередь заполнена или нет. Вы не можете сказать ему игнорировать максимальную длину, если вы ее установите.

Что вы можете сделать, это медленный производитель, если очередь слишком велика. Это позволит вам «игнорировать» максимум, если хотите. например на прерывание.

+0

Да, мне нужно подождать, если очередь заполнена. Но, как я понимаю из JavaDoc, во время ожидания может быть выбрано InterruptedException, и в этом случае метод put() остается, и мой элемент не был вставлен в очередь. Что делать в коде вызывающего абонента? –

+0

@MickaelMarrache, который зависит от ваших требований. Как правило, если ваш поток был прерван, это означает, что в вашем приложении что-то не так, и ваш поток должен прекратить обработку. Вы можете разместить объект в каком-либо месте хранения, который будет выбран другим потоком или при запуске приложения. –

+2

Прерывание исключений не означает, что что-то пошло не так в вашем приложении, это просто означает, что какой-то другой поток вызвал Thread.interrupt() в текущем потоке. Обычно это делается, когда ваше приложение хочет явно остановить поток. Вызов Thread.interrupt() является эквивалентом сообщения потока «пожалуйста, выходите так быстро, как можете» (например: потому что вы делали длинную фоновую операцию, и пользователь хочет ее отменить, или JVM было запрошено закрыть по какой-то причине), и никоим образом не свидетельствует о том, что что-то идет не так. – LordOfThePigs

Смежные вопросы