两个Class同步
Two Class Synchronization
我有 4 个 classes:Main、Producer、Consumer 和 Buffer。缓冲区 class 包含循环数组的实现(假设它有效)。生产者 class 添加到缓冲区数组,消费者 class 从缓冲区数组中删除。 Main class 为生产者和消费者创建一个线程。
在生产者内部class,如果缓冲区未满,它会添加。如果它已满,它会等到消费者从数组中删除一些东西。
在消费者内部class,如果缓冲区不为空,它会从中删除一个项目。如果它是空的,它会等到生产者向缓冲区添加一些东西。
我遇到的问题是生产者会向数组中添加项目,但每次它通知消费者它已添加到缓冲区时,消费者都处于等待状态。它永远不会继续执行其余代码。
// 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 个值(缓冲区的最大大小),但之后没有任何反应。生产者将值添加到数组中,然后进入等待状态,但是消费者没有做任何事情,因为它仍然处于等待状态。
我不明白为什么 Consumer 不继续,尽管 Producer 每次向缓冲区添加内容时都执行通知。
在您的代码中,synchronized(this)
毫无意义,因为 Consumer
和 Producer
都是独立的对象。这些对象中的每一个都有自己的 this
监视器,彼此无法访问。您被困在 while(buffer.isEmpty()) wait();
上的 Consumer
,因为 Producer
中没有任何内容调用 cosumer.notify()
。
很可能它应该是 synchronized(buffer)
(后跟 buffer.wait()
和 buffer.notify()
),因为它是代表代码中共享状态的 buffer
对象。
您正在用 Buffer
重新实现 java.util.concurrent.ArrayBlockingQueue
。为什么不使用 JDK 中已有的 class?
我有 4 个 classes:Main、Producer、Consumer 和 Buffer。缓冲区 class 包含循环数组的实现(假设它有效)。生产者 class 添加到缓冲区数组,消费者 class 从缓冲区数组中删除。 Main class 为生产者和消费者创建一个线程。
在生产者内部class,如果缓冲区未满,它会添加。如果它已满,它会等到消费者从数组中删除一些东西。
在消费者内部class,如果缓冲区不为空,它会从中删除一个项目。如果它是空的,它会等到生产者向缓冲区添加一些东西。
我遇到的问题是生产者会向数组中添加项目,但每次它通知消费者它已添加到缓冲区时,消费者都处于等待状态。它永远不会继续执行其余代码。
// 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 个值(缓冲区的最大大小),但之后没有任何反应。生产者将值添加到数组中,然后进入等待状态,但是消费者没有做任何事情,因为它仍然处于等待状态。
我不明白为什么 Consumer 不继续,尽管 Producer 每次向缓冲区添加内容时都执行通知。
在您的代码中,synchronized(this)
毫无意义,因为 Consumer
和 Producer
都是独立的对象。这些对象中的每一个都有自己的 this
监视器,彼此无法访问。您被困在 while(buffer.isEmpty()) wait();
上的 Consumer
,因为 Producer
中没有任何内容调用 cosumer.notify()
。
很可能它应该是 synchronized(buffer)
(后跟 buffer.wait()
和 buffer.notify()
),因为它是代表代码中共享状态的 buffer
对象。
您正在用 Buffer
重新实现 java.util.concurrent.ArrayBlockingQueue
。为什么不使用 JDK 中已有的 class?