Программа продюсера и потребителя работает последовательно - PullRequest
0 голосов
/ 08 сентября 2018

Я написал параллельную программу для потребителей и производителей. Но это работает последовательно: потребитель начинает потреблять только после того, как производитель не может производить, производитель начинает работать только тогда, когда нет товаров для потребителя. Предполагается, что он будет работать одновременно, потому что после производства или потребления продукта потребитель / производитель снимает блокировку и конкурирует, чтобы получить блокировку.

Однако его вывод выглядит так

Produced: 0
Produced: 1
Produced: 2
Produced: 3
Produced: 4
Queue is full Thread-0 is waiting , size: 5
Consumed: 0
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Queue is empty Thread-1 is waiting , size: 0
Produced: 5
Produced: 6
Produced: 7
Produced: 8
Produced: 9
Queue is full Thread-0 is waiting , size: 5
Consumed: 5
Consumed: 6
Consumed: 7
Consumed: 8
Consumed: 9

Моя программа выглядит следующим образом:

Потребитель:

public class Consumer implements Runnable{
    private final List<Integer> taskQueue;

    public Consumer(List<Integer> stack) {
        this.taskQueue = stack;
    }

    public void consume(){
        synchronized (taskQueue){
            while (taskQueue.isEmpty()){
                try {
                    System.out.println("Queue is empty " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
                    taskQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            Integer removeNum = taskQueue.remove(0);
            System.out.println("consume  " + removeNum);
            taskQueue.notifyAll();
        }
    }

    @Override
    public void run() {
        while (true){
            consume();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        Consumer consumer = new Consumer(list);
        Producer producer = new Producer(5, list);
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(consumer::run);
        executorService.submit(producer::run);

    }
}

Производитель:

public class Producer implements Runnable {
    private  final Integer MAX_SIZE;
    private  final List<Integer> taskQueue;

    public Producer(Integer MAX_SIZE, List<Integer> taskQueue) {
        this.MAX_SIZE = MAX_SIZE;
        this.taskQueue = taskQueue;
    }

    public void produce(int i){
        synchronized (taskQueue){
            while (taskQueue.size() == MAX_SIZE){
                System.out.println("Task queue is full.");
                try {
                    taskQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Produce "+i);
            taskQueue.add(i);
            taskQueue.notifyAll();
        }
    }

    @Override
    public void run() {
        int i = 1;
        while (true){
            produce(i++);
        }
    }
}
...