我试着为生产者和消费者做一些练习。下面的代码是线程安全的,但是这段代码不能解决生产者和使用者之间的同步问题。
码
package edu.seu.juc.pac;
import edu.seu.juc.annotation.ThreadSafe;
@ThreadSafe
public class TestProducerAndConsumer {
public static void main(String[] args) {
Clerk clerk = new Clerk();
Producer producer = new Producer(clerk);
Consumer consumer = new Consumer(clerk);
new Thread(producer, "producer A").start();
new Thread(consumer, "consumer B").start();
}
private static class Clerk {
private int product = 0;
public synchronized void get() {
if (product >= 10) {
System.out.println("product is full");
} else {
System.out.println(Thread.currentThread().getName() + " produce: " + (++product));
}
}
public synchronized void sale() {
if (product <= 0) {
System.out.println("product is lack");
} else {
System.out.println(Thread.currentThread().getName() + " consume: " + (--product));
}
}
}
private static class Producer implements Runnable {
private Clerk clerk;
public Producer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
clerk.get();
}
}
}
private static class Consumer implements Runnable {
private Clerk clerk;
public Consumer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
clerk.sale();
}
}
}
}真结果
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
product is full
product is full
product is full
product is full
product is full
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0
product is lack
product is lack
product is lack
product is lack
product is lack在我看来,结果可能如下所示--例如,--我的预期结果之一
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0volatile一定做了些什么。有人能告诉我搜索的原因或关键词吗。
发布于 2020-05-24 17:52:27
我认为当“产品满了”时,生产者应等待消费者消费产品,当“产品不足”时,消费者应等待生产者生产产品。通过这种方式,这两个线程将“串联”工作,而现在它们“按顺序”工作。
使用wait()和notifyAll()更改wait()类以实现“等待”将导致预期的输出:
private static class Clerk {
private int product = 0;
public synchronized void get() {
while (product >= 5) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
System.out.println(Thread.currentThread().getName() + " produce: " + (++product));
notifyAll();
}
public synchronized void sale() {
while (product <= 0) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
System.out.println(Thread.currentThread().getName() + " consume: " + (--product));
notifyAll();
}
}$ javac TestProducerAndConsumer.java
$ java TestProducerAndConsumer
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0
producer A produce: 1
producer A produce: 2
producer A produce: 3
producer A produce: 4
producer A produce: 5
consumer B consume: 4
consumer B consume: 3
consumer B consume: 2
consumer B consume: 1
consumer B consume: 0编辑
,但对于这个问题,我对同一线程的连续结果表示怀疑。好像是按顺序工作的。
我认为这是因为生产者和消费者在循环中运行,当“它是生产者转向”时,它重新获得对象的锁,然后消费者才有机会这样做(反之亦然)。
如果我们在每个Thread.sleep(1)和.get()和.sale()之后添加一个1毫秒的.get(),那么输出中就会出现“混合”结果:
private static class Producer implements Runnable {
private Clerk clerk;
public Producer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
clerk.get();
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private static class Consumer implements Runnable {
private Clerk clerk;
public Consumer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
clerk.sale();
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}$ javac TestProducerAndConsumer.java
$ java TestProducerAndConsumer
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0
producer A produce: 1
consumer B consume: 0https://stackoverflow.com/questions/61986582
复制相似问题