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

Producer Consumer problem - can't find the what's wrong

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

观察到的问题

代码

所有 classes 都在一个文件中,导入:

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);
        }
    }
}

class 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 代码有什么问题,但找不到任何答案。

您的 code/approach 的问题在于,您正在使用 class fun 的两个不同对象,理想情况下它们应该是多个线程之间的公共共享资源。

Inside class b you are instantiating new object of fun as shown below

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

由于 class b 的实例从未共享过,因此总是会满足以下条件

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

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

现在,要解决这个问题,您可以按照以下步骤操作

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

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

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);
        }
    }
}