Java(true)轮询队列未被执行



我正在学习Java,并且正在实现基本的生产者消费者用户酶。我有一个队列,一些生产商正在将东西插入此队列。我也有一个消费者可召唤。这是消费者的实施:

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);
}

主:

public static void main(String[] args) {
    Test();
}
public static void Test()
{
    Queue<String> queue = new LinkedList<String>();
    ScheduledExecutorService lots_of_producers = Executors.newScheduledThreadPool(10);
    ExecutorService consumers = Executors.newFixedThreadPool(1);

    for(int i=0; i<1; i++) {
        Consumer consumer = new Consumer("consumer_" + i, queue);
        consumers.submit(consumer);
    }
    for(int i=0; i<5; i++) {
        Producer producer = new Producer("producer_" + i, queue);
        lots_of_producers.scheduleWithFixedDelay(producer, i, 5, TimeUnit.SECONDS);
    }
}

生产商工作正常,但是消费者不起作用,因为我没有看到消费者的日志。

但是,如果我更改消耗实现,并在queue.isempty()为真时让消费者线程睡眠,则消费者按预期工作。

public String call() throws Exception
{
    while(true) {
        if(!queue.isEmpty()) {
            String prod = queue.poll();
            System.out.println(name + " consumed " + prod);
        } else {
            Thread.sleep(100);
        }
    }
}

任何人都可以解释为什么在第一种情况下消费者线程不起作用?

也是第一种情况,在Eclipse中,我可以看到消费者线程还没有死。我将其暂停,它在这条线上工作

        if(!queue.isEmpty()) {

现在,如果我手动翻阅,消费者将工作并打印日志。但是,一旦我恢复并让它独自运行,它将再次陷入困境。

我试图更多地了解java。

谢谢!

-erben

在这种情况下有多个问题。

  1. 您的第一个实现将运行一个紧密的循环。根据平台和螺纹模型,它可能根本不允许任何其他线程运行。这就是为什么生产者线程没有机会将数据放入队列的原因。
  2. 您的第二个实现(带有Thread.sleep)为其他线程运行提供了机会。这就是为什么您会看到消费者消耗某些东西的原因,因为生产者线程有机会将数据放在队列中。但是,即使您尚未同步生产商和消费者,即使是该失败也开放。参见Java教程 - 学习线程同步的同步。

最新更新