Java线程生产者消费者程序

标签 java multithreading thread-safety

我正在尝试用Java编写一个生产者消费者程序,其中生产者在队列中插入3个数字,消费者从队列中删除这些数字。我根据自己的 Linkedlist 实现实现了自己的队列。

当我运行代码时,我的生产者终止,但我的消费者永远不会终止。我不明白为什么

public class ProdConMain {

public static void main(String[] args) throws InterruptedException {

    MyQueue queue = new MyQueue();
    queue.setLimit(3);
    Thread producer = new Thread(new Producer(queue));
    Thread consumer = new Thread(new Consumer(queue));

    producer.start();
    consumer.start();


    try {
        producer.join();
        System.out.println("Producer: " + producer.getState());
        consumer.join();

        System.out.println("Consumer: " + consumer.getState());
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println(queue.list.toString());

}


}



public class Producer implements Runnable {

MyQueue queue = new MyQueue();
Random random = new Random();
public Producer(MyQueue queue) {
    this.queue = queue;
}

@Override
public void run() {
    int i = 1;
    while (i < 10) {

        synchronized (queue) {
            if (queue.getSize() < queue.getLimit()) {
                int value = random.nextInt(500);
                queue.enqueue(value);
                System.out.println("Inserted: " + value);
                queue.notify();
            } else {
                try {
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        i++;
    }
  }
}


public class Consumer implements Runnable {

  MyQueue queue = new MyQueue();

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

  @Override
  public void run() {

     while (true) {
        synchronized (queue) {

            if (queue.isEmpty()) {
                {
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } else {
                int value = queue.dequeue();
                System.out.println("Removed:        " + value);
                queue.notify();
            }
        }
    }
  }
}

最佳答案

您需要向消费者中的 while(true) 循环添加停止条件,否则它将永远不会完成。您可以在 while 条件本身中执行此操作:

while(shouldConsume()) { 
    // consume ...
}

或者在达到条件时中断无限循环:

while(true) { 
    // consume ...

    if (shouldStopConsume()) {
        break;
    }
}

然后您只需使用适合您的用例的停止条件来实现这些方法。

关于Java线程生产者消费者程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38815416/

相关文章:

java - 服务 spring 上的 NullPointerException

java - J2ME 中的同步

c++ - 线程安全三角测量库

java - Java中如何使用锁来等待特殊条件?

c# - 为什么我没有看到 IDisposable 实现并发的任何实现?

java - Spring MVC 一步一步进入 Maven

java - 检查加扰字符串的字符是否与第二个字符串匹配

java - Epoch 迄今为止无法正常工作

multithreading - goroutines是如何调度的?

multithreading - Docker 容器而不是多处理