当前位置: 首页 > 知识库问答 >
问题:

Java线程生产者消费者:代码有什么问题?

苏嘉志
2023-03-14

尝试学习线程的多线程和进程间通信。实施了一个典型的生产者-消费者问题。然而,am获得的输出是相当连续的,这在理想情况下不应该是使用线程的情况。

好的,下面是完整的代码:

public class ProducerConsumerSimulation {


public static ProducerConsumerSimulation simulation = new ProducerConsumerSimulation();


private Queue<Integer> sharedQueue = new LinkedList<Integer>();

private int MAX_LIMIT =  10;

public void produce(int i){
    synchronized (sharedQueue) {
        while(true){


            while(sharedQueue.size()==MAX_LIMIT){
                try {
                    sharedQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } 
            sharedQueue.add(i);
            System.out.println("Produced: "+i);
            sharedQueue.notifyAll();
            return;


        }
    }
}

public void consume() {
    synchronized (sharedQueue) {
        while (true) {


            while (sharedQueue.isEmpty()) {
                try {
                    sharedQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } 
            int i = sharedQueue.remove();
            System.out.println("Consumed: " + i);
            sharedQueue.notifyAll();
            return;


        }
    }
}

/**
 * @param args
 */
public static void main(String[] args) {


    for(int i=1;i<=5;i++){

        Runnable p = new Producer();
        Thread prod = new Thread(p);
        prod.start();
    }
    for(int i=1;i<=5;i++){

        Runnable c = new Consumer();
        Thread con = new Thread(c);
        con.start();
    }


}

}

生产者线程:

public class Producer implements Runnable {

/* (non-Javadoc)
 * @see java.lang.Runnable#run()
 */
@Override
public void run() {

    for(int i=1;i<=10;i++){
        ProducerConsumerSimulation.simulation.produce(i);
    }

}

}

使用者线程:

public class Consumer implements Runnable {

/* (non-Javadoc)
 * @see java.lang.Runnable#run()
 */
@Override
public void run() {

    for(int i=1;i<=10;i++){
        ProducerConsumerSimulation.simulation.consume();
    }

}

}

现在,当我运行程序时,生产者线程总是比消费者线程先运行。即使我创建了多个生产者/消费者,结果也是一样的。以下是单个生产者和单个消费者的产量:

Produced: 1
Produced: 2
Produced: 3
Produced: 4
Produced: 5
Produced: 6
Produced: 7
Produced: 8
Produced: 9
Produced: 10
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Consumed: 5
Consumed: 6
Consumed: 7
Consumed: 8
Consumed: 9
Consumed: 10

有人能解释一下这里的行为吗?我已经在这里读了很多答案,但我想知道我是否错误地执行了或其他。

共有1个答案

金子轩
2023-03-14

首先,您应该删除这两个while(true)循环,它们实际上只执行一次,因为您在第一次迭代后返回。它使您的代码相当混乱。

现在,关于您的问题:生产者和消费者在两个生产/消费之间都不做任何事情。它们立即重新进入同步块,以便将某些内容放入队列/从队列中获取某些内容。更实际的例子是在将值放入队列之前需要一些时间来生成这些值,并且需要一些时间来处理从队列中获得的值。如果在每次调用produce()或consumer()之后引入任意延迟,您将开始看到更多交错的生产和消耗。

最后,请注意,通过使用LinkedList、synchronized块和对wait/notifyAll的调用,您正在重新设计轮子。您应该只使用BlockingQueue,这对您来说就够了。

 类似资料:
  • 我有两个线程的问题,似乎没有正确同步。我基本上有一个布尔值名为“已占用”。当没有线程启动时,它被设置为false。但是当一个线程启动时,线程集被占用是真的,我有一个类,它有线程(run),它们调用下面的函数。 这是一个模拟银行的示例,它接收一个金额(初始余额),然后随机执行取款和存款。我的教授提到了一些关于从取款线程到存款线程的信号?这是怎么回事?在提取线程中,它应该运行到余额为2低,并等待存款线

  • 所谓的生产者消费者模型就是 某个模块(函数)负责生产数据,这些数据由另一个模块来负责处理 一般生产者消费者模型包含三个部分 生产者、缓冲区、消费者 为什么生产者消费者模型要含三个部分?直接生产和消费不行么? 一个案例说明一切 生产者好比现实生活中的某个人 缓冲区好比现实生活中的邮箱 消费者好比现实生活中的邮递员 如果只有生产者和消费者, 那么相当于只有写信的人和邮递员,那么如果将来过去的邮递员离职

  • 我有一个生产者-消费者模式的多线程任务。可能有许多生产者和一个消费者。我使用ArrayBlockingQueue作为共享资源。 Producer类中的run()方法: Consumer类中的run()方法: main()方法: 现在,当队列为空时,我有消费者结束条件。但是可能会有一段时间队列变成空的,但是一些生产者线程仍然在工作。所以我只需要在完成所有生产者线程之后才完成消费者线程(但它们的数量事

  • 本文向大家介绍java 中多线程生产者消费者问题详细介绍,包括了java 中多线程生产者消费者问题详细介绍的使用技巧和注意事项,需要的朋友参考一下 java 中多线程生产者消费者问题 前言: 一般面试喜欢问些线程的问题,较基础的问题无非就是死锁,生产者消费者问题,线程同步等等,在前面的文章有写过死锁,这里就说下多生产多消费的问题了 这个是jdk版本1.5以上的多线程的消费者生产者问题,其中优化的地

  • 本文向大家介绍Java如何通过线程解决生产者/消费者问题,包括了Java如何通过线程解决生产者/消费者问题的使用技巧和注意事项,需要的朋友参考一下 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示 生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生

  • 问题内容: 我想创建某种线程应用程序。但是我不确定在两者之间实现队列的最佳方法是什么。 因此,我提出了两个想法(这两个想法可能都是完全错误的)。我想知道哪种更好,如果它们都烂了,那么实现队列的最佳方法是什么。我关心的主要是这些示例中队列的实现。我正在扩展一个内部类的Queue类,它是线程安全的。下面是两个示例,每个示例有4个类。 主班 消费阶层 生产者类别 队列类 要么 主班 消费阶层 生产者类别