生产者消费者问题 - 找不到问题

时间:2021-07-12 16:21:30

标签: java multithreading producer-consumer

我是 Java 初学者,正在尝试使用 Java 中的多线程来解决生产者消费者问题。

观察到的问题

  • 一个线程没有执行,我找不到原因。
  • 没有任何错误,但输出不匹配。
  • 生产者线程正在运行,但消费者仍未运行。

代码

所有类都在一个带有导入的文件中:

import java.util.LinkedList;
import java.util.*;

为了便于阅读,我将它们分开在这里。

class fun {
    LinkedList<Integer> list = new LinkedList<>();
    int capacity=3;
    
    synchronized void produce()throws InterruptedException {
        int val=0;
        while(true) {
            while(list.size() == capacity) {
                wait();
            }
            System.out.println("Producer Produced : "+val);
            list.add(val);
            val++;
            notify();
        }
    }
    
    synchronized void consume() throws InterruptedException { 
        while(true) {
            while(list.size() == 0) {
                wait();
            }
            int val;
            val = list.removeFirst();
            System.out.println("Consumer consumed-"+ val);
            notify();
        }
    }
}

class a 定义一个线程:

class a extends Thread {
    public void run() {
        try {
            fun obj=new fun();
            obj.produce();
        } catch(InterruptedException e) {
            System.out.println(e);
        }
    }
}

class b 定义另一个线程:

class b extends Thread {
    public void run() {
        try {
            fun obj=new fun();
            obj.consume();
        } catch(InterruptedException e) {
            System.out.println(e);
        }
    }
}

pcp 包含 main 方法:

class pcp {
    public static void main(String[]args) throws InterruptedException {
        a t1=new a();
        b t2=new b();
        t1.start();
        System.out.println(t1.isAlive());
        t2.start();
        System.out.println(t1.isAlive());
        t1.join();
        t2.join();
    }
}

输出

C:\javaprogs>java pcp
true
true
Producer Produced : 0
Producer Produced : 1
Producer Produced : 2

我一直在检查我的 Java 代码有什么问题,但找不到任何答案。

1 个答案:

答案 0 :(得分:0)

您的代码/方法的问题在于,您使用了类 fun 的两个不同对象,理想情况下它们应该是多个线程之间的公共共享资源。

<块引用>

在类 b 中,您将 fun 的新对象实例化为 如下图

try{    
    fun obj=new fun();
    obj.consume();
}

由于从未共享类 b 的实例,因此始终满足以下条件

while(list.size() == 0) {
      wait();
}

并且不会有其他线程通知此等待线程,因为您的生产者线程正在处理 a 的监视器;不是b。这导致您的生产者线程继续只打印上述内容。

现在,要摆脱此问题,您可以按照以下步骤操作

  1. 考虑将 fun 声明为类 ab 的成员
  2. ab 中提供一个接受 fun 类型的构造函数并使用成员变量对其进行初始化
  3. run() 方法中,尝试对 produce() 成员变量调用 consume()fun
  4. 最后一步是,在您的 main 中,创建一个 fun 对象并使用它来创建 ab 的实例

对您的代码进行一些修改的完整代码如下所示。

import java.util.*;

public class pcp {
    public static void main(String[] args) throws InterruptedException {
        fun f = new fun();
        a t1=new a(f);
        b t2=new b(f);
        t1.start();
        System.out.println(t1.isAlive());
        t2.start();
        System.out.println(t1.isAlive());
        t1.join();
        t2.join();
    }
}

class fun {
    LinkedList<Integer> list = new LinkedList<>();
    int capacity = 3;

    synchronized void produce() throws InterruptedException {
        int val = 0;
        while (true) {
            while (list.size() == capacity) {
                wait();
            }
            System.out.println("Producer Produced : " + val);
            list.add(val);
            val++;
            notify();
            Thread.sleep(1000);
        }
    }

    synchronized void consume() throws InterruptedException {
        while (true) {
            while (list.size() == 0) {
                wait();
            }
            int val;
            val = list.removeFirst();
            System.out.println("Consumer consumed-" + val);
            notify();
            Thread.sleep(1000);
        }
    }
}

class a extends Thread {
    fun f;
    a(fun f) {
        this.f = f;
    }
    public void run() {
        try {
            f.produce();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
    }
}

class b extends Thread {
    fun f;
    b(fun f) {
        this.f = f;
    }
    public void run() {
        try {
            f.consume();
        } catch (InterruptedException e) {
            System.out.println(e);
        }
    }
}
相关问题