Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.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 while(true)轮询未执行的队列_Java_Multithreading_Executorservice_Producer Consumer - Fatal编程技术网

java while(true)轮询未执行的队列

java while(true)轮询未执行的队列,java,multithreading,executorservice,producer-consumer,Java,Multithreading,Executorservice,Producer Consumer,我正在学习java,我正在实现一个基本的生产者-消费者用例。 我有一个队列和一些制作人,他们正在向这个队列中插入内容。 我还有一个实现Callable的消费者。以下是消费者体验的实现: public String call() throws Exception { while(true) { if(!queue.isEmpty()) { String prod = queue.poll(); System.out.print

我正在学习java,我正在实现一个基本的生产者-消费者用例。 我有一个队列和一些制作人,他们正在向这个队列中插入内容。 我还有一个实现Callable的消费者。以下是消费者体验的实现:

public String call() throws Exception
{
    while(true) {
        if(!queue.isEmpty()) {
            String prod = queue.poll();
            System.out.println(name + " consumed " + prod);
        }
    }
}
制作人:

@Override
public void run() {
    System.out.println("adding " + name);
    queue.add(name);
}
主要内容:

有人能解释为什么消费者线程在第一种情况下不起作用吗

同样对于第一种情况,在eclipse中,我可以看到消费者线程并没有死。我暂停了它,它正在这条线上工作

        if(!queue.isEmpty()) {
现在,如果我手动跳过,消费者将工作并打印日志。但一旦我恢复并让它自己运行,它就会再次卡住

我正在努力更多地理解java

谢谢


-埃尔本

在这种情况下存在多个问题

  • 您的第一个实现运行一个紧密的循环。根据平台和线程模型的不同,它可能根本不允许运行任何其他线程。这就是生产者线程没有机会将数据放入队列的原因
  • 您的第二个实现(使用
    Thread.sleep
    )为其他线程提供了运行的机会。这就是为什么您看到消费者消费某些东西的原因,因为生产者线程有机会将数据放入队列中。但是,即使是这一个也可能失败,因为您没有同步生产者和消费者。有关学习线程同步的信息,请参阅

  • 在这种情况下存在多个问题

  • 您的第一个实现运行一个紧密的循环。根据平台和线程模型的不同,它可能根本不允许运行任何其他线程。这就是生产者线程没有机会将数据放入队列的原因
  • 您的第二个实现(使用
    Thread.sleep
    )为其他线程提供了运行的机会。这就是为什么您看到消费者消费某些东西的原因,因为生产者线程有机会将数据放入队列中。但是,即使是这一个也可能失败,因为您没有同步生产者和消费者。有关学习线程同步的信息,请参阅

  • 您应该使用某种类型的
    阻塞队列
    。您没有显示代码的另一面,但我怀疑您没有使用适当的线程安全队列实现。可能您的使用者任务已死亡(例如,由于并发修改异常),如果发生这种情况,您将看不到任何异常,因为执行器将返回一个结果或异常,而不是产生嘈杂的崩溃。手动创建线程同步非常困难,而且容易出现错误!使用JDK本身提供的API.lol。我找到了原因。Java linkedlist不是线程安全的。我将调用包装在synchronized(queue)中,它甚至可以在不使用thread.sleep的情况下工作。所以我学到了两件事:1。java很好地处理线程。单个线程中的紧密循环不会影响其他线程。2.linkedlist不是线程安全的,竞争条件将导致未定义的行为(如挂起)。谢谢大家!您应该使用某种类型的
    阻塞队列
    。您没有显示代码的另一面,但我怀疑您没有使用适当的线程安全队列实现。可能您的使用者任务已死亡(例如,由于并发修改异常),如果发生这种情况,您将看不到任何异常,因为执行器将返回一个结果或异常,而不是产生嘈杂的崩溃。手动创建线程同步非常困难,而且容易出现错误!使用JDK本身提供的API.lol。我找到了原因。Java linkedlist不是线程安全的。我将调用包装在synchronized(queue)中,它甚至可以在不使用thread.sleep的情况下工作。所以我学到了两件事:1。java很好地处理线程。单个线程中的紧密循环不会影响其他线程。2.linkedlist不是线程安全的,竞争条件将导致未定义的行为(如挂起)。谢谢大家!
    public String call() throws Exception
    {
        while(true) {
            if(!queue.isEmpty()) {
                String prod = queue.poll();
                System.out.println(name + " consumed " + prod);
            } else {
                Thread.sleep(100);
            }
        }
    }
    
            if(!queue.isEmpty()) {