Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java BlockingQueue take()在while循环中_Java_Asynchronous_Blockingqueue - Fatal编程技术网

Java BlockingQueue take()在while循环中

Java BlockingQueue take()在while循环中,java,asynchronous,blockingqueue,Java,Asynchronous,Blockingqueue,我有一个BlockingQueue,它由一个带有put()的线程填充。但是我对如何为阻塞队列执行take()感到困惑。目前我是这样实现的: String link; try { while(!(link = links.take()).isEmpty()) { System.out.println(link); } } catch(InterruptedException ex) { ex.printStackTrace(); } 是这样吗?如果不在条件

我有一个BlockingQueue,它由一个带有put()的线程填充。但是我对如何为阻塞队列执行take()感到困惑。目前我是这样实现的:

String link;
try {
    while(!(link = links.take()).isEmpty()) {
        System.out.println(link);
    }
} catch(InterruptedException ex) {
    ex.printStackTrace();
}

是这样吗?如果不在条件语句中,如何循环队列并分配字符串变量?

我的理解是,您正在询问如何以良好的方式终止BlockingQueue。我可以想到两种情况。在任何情况下,您都有消息生产者a和消息消费者B

  • 消息生成器发送某种形式的终端值,如“Stop”。您对照它进行检查,while循环终止
  • 您可以中断消息生成器,它将在使用者端抛出InterruptedException。这是避免终端输入情况的方法。这里的问题是,如果消费者实际消费了队列中的所有内容,您无法控制。因此,如果存在需要消费立即终止的情况,通常会使用中断

  • 如果我理解正确,您是否询问了一种方法,使
    脱离条件?嗯,没那么难:

    while(!links.isEmpty()){
    试一试{
    String link=links.take();
    //做事。
    }捕捉(中断异常e){
    //异常处理。
    }
    }
    
    您当前的状况
    !(link=links.take()).isEmpty()
    检查返回值a字符串是否为空(长度等于0),而不是队列

    无论如何,请记住上面的代码不是,因此不能保证
    links.isEmpty()
    links.take()
    之间不会发生任何其他事情

    编辑:您可以在启动期间使用以下标志进行处理:

    BlockingQueue number=newarrayblockingqueue(10);
    AtomicBoolean标志=新的AtomicBoolean(真);
    //制片人。
    新线程(()->{
    对于(int i=0;i<10;i++){
    试一试{
    数字。付诸表决(i);
    }catch(InterruptedException e){/*NOP*/}
    }
    flag.set(false);
    }).start();
    //消费者。
    while(flag.get()| |!numbers.isEmpty()){
    试一试{
    System.out.println(number.take());
    }catch(InterruptedException e){/*NOP*/}
    }
    

    这里不需要,但是如果您有多个生产者和/或消费者,它可能会变得很方便。这也是您绝对应该检查的一部分。

    但另一个问题是,在生产者代码中,消费者处理了一定数量的元素后,是否可以知道何时停止生产?您可以异步执行此操作。假设您想要消费
    n
    项,那么您可以创建一个
    ArrayBlockingQueue
    ,其容量为
    n
    put
    仅当队列中没有足够的空间时才会阻塞,这样您的制作人就可以发射并忘记。但是
    从消费者那里获取
    将腾出空间,制作人将继续放入队列,因此,它只会暂停生产者,但我希望消费者处理多个项目后,生产者会完全停止。只需将
    put
    的调用包装在一个for循环中,该循环在
    n
    迭代后终止。这样,您的制作人将准确地提交
    n
    项目。消费者可以独立地
    使用
    。好吧,回到最初的问题,我刚刚尝试了你的解决方案,发现当执行while循环时,制作人没有
    放入
    链接
    ,从而完全跳过while循环。我应该怎么做才能使while循环等待插入到队列中的内容?