почему программа зависает при использовании ArrayBlockingQueue

#java #java.util.concurrent

#java #java.util.concurrent

Вопрос:

У меня возникла проблема при использовании ArrayBlockingQueue .

Вот мой код:

 package study;

import org.pmw.tinylog.Logger;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class App {
    public static void main(String[] args) throws Exception {
        BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1024);
        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);

        new Thread(producer).start();
        new Thread(consumer).start();

        Thread.sleep(1000);
    }
}

class Producer implements Runnable {
    protected BlockingQueue<String> queue = null;

    public Producer(BlockingQueue<String> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 100000; i  ) {
                queue.put(String.valueOf(i));
                //Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            Logger.info(e);
        }
    }
}

class Consumer implements Runnable {
    protected BlockingQueue queue;

    public Consumer(BlockingQueue queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            Logger.info(queue.take());
            //Logger.info(queue.take());
            //Logger.info(queue.take());
        } catch (InterruptedException e) {
            Logger.info(e);
        }
    }
}
  

Но результат:

 2016-10-24 14:08:27 [Thread-1] study.Consumer.run()
INFO: 0
  

Я не думаю, что это правильно, но я не могу найти проблему.

Ответ №1:

Измените свой Consumer запуск на цикл, так как на данный момент вы удаляете из очереди только первый элемент, в то время как Producer в очередь было помещено 100000.

  public void run() {
  while (true) {
    try {
        Logger.info(queue.take());
        //Logger.info(queue.take());
        //Logger.info(queue.take());
    } catch (InterruptedException e) {
        Logger.info(e);
    }
  }
}
  

Комментарии:

1. Хотя это устраняет проблему — это не ответ, вам следует добавить некоторые подробности о том, почему это устраняет проблему.

2. @Raniz Тогда ладно.

Ответ №2:

Вы запускаете

 Logger.info(queue.take());
  

в результате потребитель завершает работу только один раз, получив ОДИН ‘0’ из очереди. Просто добавьте цикл while, подобный

 while(true) {
    Logger.info(queue.take());
}