java线程阻塞队列,需要澄清
在使用BlockingQueue
时,我实现了以下逻辑,以便从中读取,直到被告知另一个逻辑。不幸的是,以下情况时断时续地发生:
问题是:
- 即使在shouldContinueReading设置为false之后,循环也不会一直中断
- 问题是间歇性的,有时一切正常
作为QThread类的一部分,我声明:
public static volatile boolean shouldContinueReading = true;
运行(确认正在执行)方法包含:
while (shouldContinueReading) {
try {
String retrieved = qIn.poll(2, TimeUnit.MILLISECONDS);
if (retrieved != null)
consume(retrieved);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("I am out"); // <-- not always seen
if (qIn.remainingCapacity() > 0) {
try {
consume(qIn.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
在另一个线程中,当某些事情发生时,shouldContinueReading
会改变状态
while (stillReading) {
// do nothing
}
QThread.shouldContinueReading = false;
更新:问题已解决
事实证明,问题还远不止于此:
private void consume(String take) {
// some processing
produce(newData.toString());
}
private void produce(String newData) {
System.out.println(newData);
try {
qOut.put(newData); // <-- Problem is here. Should use offer instead of put
} catch (InterruptedException e) {
e.printStackTrace();
}
}
qIn(排队进入)和qOut(排队离开)均声明为:
private volatile BlockingQueue<String> qIn;
private volatile BlockingQueue<String> qOut;
对象本身在其他地方创建,如下所示,并传递给构造函数:
BlockingQueue<String> q1 = new SynchronousQueue<String>();
BlockingQueue<String> q2 = new SynchronousQueue<String>();
QThread qThread = new QThread(q1, q2);
有什么建议吗?我该拿库特怎么办?我说的不对吗
# 1 楼答案
我敢打赌
QThread.shouldContinueReading = false;
并不是总是被执行,或者读取线程一开始就没有执行。也就是说,你看到的问题可能是上游的某个地方,而不是这里。我要做的第一件事是以100%的信心确定问题的确切位置(多打印一些声明)除了这个问题,我建议使用线程中断机制,而不是滚动你自己的标志(这反过来只是一个美化的标志,但这样你可以影响像
BlockedQueue
这样的第三方代码,使实现更简单、更高效),尤其是如果这是生产代码的话