Var*_*rde 6 java collections multithreading java.util.concurrent
我试图在BlockingQueue上使用迭代器方法并发现hasNext()是非阻塞的 - 即它不会等到添加更多元素,而是在没有元素时返回false.
所以这里是问题:
这是一个示例代码块
public class SomeContainer{
public static void main(String[] args){
BlockingQueue bq = new LinkedBlockingQueue();
SomeContainer h = new SomeContainer();
Producer p = new Producer(bq);
Consumer c = new Consumer(bq);
p.produce();
c.consume();
}
static class Producer{
BlockingQueue q;
public Producer(BlockingQueue q) {
this.q = q;
}
void produce(){
new Thread(){
public void run() {
for(int i=0; i<10; i++){
for(int j=0;j<10; j++){
q.add(i+" - "+j);
}
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
}
static class Consumer{
BlockingQueue q;
public Consumer(BlockingQueue q) {
this.q = q;
}
void consume() {
new Thread() {
public void run() {
Iterator itr = q.iterator();
while (itr.hasNext())
System.out.println(itr.next());
}
}.start();
}
}
}
Run Code Online (Sandbox Code Playgroud)
此代码仅打印最多一次迭代.
Sea*_*oyd 10
只是不要将迭代器与队列一起使用.使用peek()或poll()替代或take()如果它是BlockingQueue:
void consume() {
new Thread() {
@Override
public void run() {
Object value;
// actually, when using a BlockingQueue,
// take() would be better than poll()
while ((value=q.poll())!=null)
System.out.println(value);
}
}.start();
}
Run Code Online (Sandbox Code Playgroud)
A Queue是Iterable因为它是a Collection并因此需要提供一种iterator()方法,但不应该使用它,或者你不应该首先使用Queue.
1)这是糟糕的设计,还是错误的期望?
错误的期望,因为否则它会违反迭代器的契约,该契约上Iterator.next()说:Throws: NoSuchElementException - iteration has no more elements.
如果next()会阻塞,则永远不会抛出异常。
2)有没有办法使用阻塞方法
是的,例如通过扩展类并重写next和hasNext方法来改为使用阻塞例程。请注意,在这种情况下hasNext需要始终返回true- 这再次违反了合同。
| 归档时间: |
|
| 查看次数: |
9920 次 |
| 最近记录: |