在生产者消费者问题中,线程间通信没有发生代码卡在某个点

In Producer consumer problem inter thread communication is not happening the code gets stuck at a certain point

我在 java 中解决生产者消费者问题,但我的代码卡在 System.out.println("In condition in produce method " ) 这个 line.I 认为由于我的代码无法执行 consume method。那么谁能帮我解决这个问题并告诉我这背后的原因是什么以及应该在代码中进行哪些修改。


import java.util.LinkedList;
class Consumer extends Thread {
    public void run()
    {
        try{
            PC p = PC.getInstance();

            p.consume();
            Thread.sleep(500);
        }
        catch(Exception e ){
        System.out.println(e);
    }
    }
}
class Producer extends Thread{

    public void run (){
        PC p = PC.getInstance();
        try{

            p.produce();
            Thread.sleep(500);
        }
        catch(Exception e){
            System.out.println("interrupted");
        }
    }
}
class PC {
     LinkedList a = new LinkedList();
    int capacity = 2;
    private static PC single_instance = null;

    public static PC getInstance()
    {
        if (single_instance == null)
            single_instance = new PC();

        return single_instance;
    }

    public    void consume() throws InterruptedException{
        while (true) {
            synchronized (this) {
                while (a.size() == 0) {
                    System.out.println("here I am  ");
                    wait();
                }

                int val = (int) a.removeFirst();
                System.out.println("consumer consumed" + val);
                notify();
                Thread.sleep(500);
            }
        }
    }
    public    void produce() throws InterruptedException {

       while(true) {
           int value = 0;
           synchronized (this) {

               while (a.size() == capacity) {
                   System.out.println("In condition in produce method " );////
                   wait();
               }


               System.out.println("producing  value " + value);
               a.add(value++);
               notify();
               System.out.println("after notify in produce method" );
               Thread.sleep(500);
           }
       }
    }
}
public class multithreading {
    public static void main(String[] args) throws InterruptedException {

        Producer p1 = new Producer();
       // Producer p2 = new Producer();

        Consumer c1 = new Consumer();
        p1.start();
        c1.start();

        p1.join();
        c1.join();
    }
}

我只得到输出到此为止

producing  value 0
after notify in produce method
producing  value 0
after notify in produce method
In condition in produce method 

Process finished with exit code 130

这很糟糕:

synchronized(this) {
    ...
    Thread.sleep(...);
    ...
}

这很糟糕,因为正在休眠的线程无缘无故地将其他线程锁定在临界区之外。这就像,两个室友共用一辆车,但其中一个室友拿着钥匙然后上床睡觉。为什么第一个室友睡觉时不让另一个室友用车?

这也不好:

while (true) {
    synchronized(this) {
        ...
    }
}

这很糟糕,因为线程在离开临界区后所做的下一件事就是尝试 re-enter 临界区。 Java 的内部锁不是 fair。刚离开同步块的线程在尝试 re-enter 时已经 运行ning。另一个线程被阻塞等待轮到它。在那种情况下,OS 总是会选择已经是 运行ning 的线程,因为在 well-architected 程序中——即在一个室友不睡觉的程序中使用车钥匙——这是通常会产生最佳性能的策略。

System.out.println() 调用和 Thread.sleep() 调用移出 synchronized(this) 块,这将使另一个线程有更好的机会 运行:

while (true) {
    synchronized(this) {
        ...
        notify();
    }
    System.out.println("...");
    Thread.sleep(500);
}

@Gardener 可能已经确定了您的问题:您的单例不是 thread-safe(参见上面 Gardener 的评论)。您应该在某些静态对象上同步静态 getInstance() 方法。 (PC class 对象可以工作。)

public static PC getInstance()
{
    synchronized(PC.class) {
        if (single_instance == null) {
            single_instance = new PC();
        }

        return single_instance;
    }
}

这不太好:

...
catch (Exception e) {
    System.out.println(e);              // not great
    System.out.println("interrupted");  // even less great
}

它不是很好,因为如果发生异常,它只为您提供最少的信息。改为执行此操作以在标准错误输出流上获取详细消息,准确说明异常发生的位置:

...
catch (Exception e) {
    e.printStackTrace();
}