两类同步

问题描述 投票:0回答:1

我有4个类:Main,Producer,Consumer和Buffer。缓冲区类包含圆形数组的实现(假设它可以工作)。生产者类添加到缓冲区数组,而消费者类从缓冲区数组中删除。 Main类为生产者和消费者创建线程。

在生产者类内部,如果缓冲区未满,它将添加到其中。如果已满,它将等待,直到使用者从阵列中移除某些东西为止。

在Consumer类中,如果缓冲区不为空,它将从其中删除一个项目。如果为空,则等待生产者向缓冲区中添加一些东西。

我遇到的问题是生产者将向数组添加项目,但是每次它通知使用者它已添加到缓冲区时,使用者都处于等待状态。它永远不会继续其余的代码。

// Main.java
Buffer buffer = new Buffer(5); // creates a circular array of length 5.

// 10 is total number of items to be added
Producer p = new Producer(buffer, 10); // uses random number generator for values 
Consumer c = new Consumer(buffer, 10);

p.start();
c.start();

p.join();
c.join();
public class Producer extends Thread {

    ...

    public void run() { 
        ...
        while(true) {
            synchronized(this) {
                try {
                    while(buffer.isFull()) wait(); 
                    ...
                    buffer.insert(val);
                    notify();
                    ... // other stuff that eventually breaks the loop
                } catch(InterruptedException e) {}
            }
        }
    }
}
public class Consumer extends Thread {

    ...

    public void run() {
        while(true) {
            synchronized(this) {
                try {
                    while(buffer.isEmpty()) wait(); // its stuck here
                    ...
                    buffer.remove();
                    notify();
                    ... // other stuff that eventually breaks the loop
                } catch (InterruptedException e) {}
            }
        }
    }
}

// Inside Buffer.java

public void insert(int n) {
    ...
    buffer[front] = n;
    front++;
    size++;
}

public int remove() {
    ...
    temp = buffer[rear] = -1;
    rear--;
    size--;
    return temp;
} 

在生产者中,有一个打印语句,该语句打印出添加到缓冲区的5个值(缓冲区的最大大小),但是此后什么也没有发生。生产者将值添加到数组,然后进入等待状态,但是消费者不执行任何操作,因为它仍然保持在等待状态。

我不知道为什么每次生产者在缓冲区中添加内容时,尽管生产者仍在执行通知,消费者仍然无法继续。

java multithreading synchronized
1个回答
1
投票

在您的代码中,synchronized(this)是毫无意义的,因为ConsumerProducer都是独立的对象。这些对象中的每一个都有其自己的this监视器,其他监视器无法访问。您被困在Consumerwhile(buffer.isEmpty()) wait();中,因为Producer中的任何内容都不会调用cosumer.notify()

[最有可能应该是synchronized(buffer)(后跟buffer.wait()buffer.notify()),因为它是代表代码中共享状态的buffer对象。

您正在用java.util.concurrent.ArrayBlockingQueue重新实现java.util.concurrent.ArrayBlockingQueue。为什么不使用JDK中已经提供的类?

© www.soinside.com 2019 - 2024. All rights reserved.