2012-06-13 112 views
1

我有一个LinkedBlockingQueue作为属性的类A。在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

好吧,如果你的线程被中断,正确的行为是尽可能早地停止该线程(这是中断一个线程的目的)。在确定项目在队列中之前,您不希望线程退出,但是您也应该尊重之前收到的InterruptedException的含义。这可能与您的情况无关,但这就是最后一条if语句用于我的情况。 – LordOfThePigs

+0

在哪种情况下,被中断的线程应该退出?为什么你认为我们应该从异常中理解某些“出错”,并且我们需要准备关闭线程? –

3

你必须决定是否要等待如果队列已满。如果你设置它,你不能让它忽略最大长度。

如果队列太大,你可以做的是减慢生产者。如果你愿意,这将允许你“忽略”最大值。例如在一个中断。

+0

是的,我需要等待,如果队列已满。但是,正如我从JavaDoc了解的那样,在等待过程中可能会抛出InterruptedException,在这种情况下,put()方法会被留下,并且我的项目尚未插入到队列中。我应该在呼叫者代码中做什么? –

+0

@MickaelMarrache取决于您的要求。一般来说,如果你的线程被中断了,这意味着你的应用程序出了问题,你的线程应该停止处理。您可以将对象放置在某个存储位置,以供其他线程或应用程序启动时使用。 –

+2

InterruptedException并不表示应用程序中出现了问题,而仅表示其他某个线程在当前线程上调用了Thread.interrupt()。通常,只要您的应用程序想要显式停止线程,就会执行此操作。调用Thread.interrupt()相当于告诉线程“请尽快退出”(例如:因为您正在执行一个简单的后台操作,并且用户想取消它,或者JVM被请求关闭出于某种原因),并不意味着出现问题。 – LordOfThePigs