对于经典的操作系统中的生产者/消费者问题,用Java语言编程实现。
问题:在一个共享空间可存储n个数,
生产者1随机产生一个奇数,打印并放入共享空间;生产者2随机产生一个偶数,打印并放入共享空间;
消费者1从共享空间中取出奇数,打印所有取出奇教的总和;消费者2从共享空间中取出偶数,打印所有取出偶数的总和。
思路:
1.共享存储空间未满,生产者可进行存数据;存储满,wait()等待(放弃lock),阻塞,等待notifyAll()唤醒。
2.共享存储空间不空(有数据),可读取数据;若空,则消费者wait()等待(放弃lock),阻塞,等待notifyAll()唤醒。
package org.example;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
public class ProducerConsumerExample {
private static final int maxSize = 10;
public static void main(String[] args) {
Queue<Integer> sharedQueue = new LinkedList<>();
//lock同步锁 实现进程同步
Object lock = new Object();
long start = System.currentTimeMillis();
Thread producer1 = new Producer(sharedQueue, maxSize, lock, true,start);
Thread producer2 = new Producer(sharedQueue, maxSize, lock, false,start);
Thread consumer1 = new Consumer(sharedQueue, lock, true,start);
Thread consumer2 = new Consumer(sharedQueue, lock, false,start);
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
}
static class Producer extends Thread {
private final Queue<Integer> queue;
private final int maxSize;
private final Object lock;
private final boolean isOddProducer;
private final long start;
public Producer(Queue<Integer> queue, int maxSize, Object lock, boolean isOddProducer,long start) {
this.queue = queue;
this.maxSize = maxSize;
this.lock = lock;
this.isOddProducer = isOddProducer;
this.start = start;
}
@Override
public void run() {
while (System.currentTimeMillis()-start< time.overTime) {
//同步代码块
synchronized (lock) {
while (queue.size() == maxSize) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Random random = new Random();
int number = random.nextInt(100);
if ((isOddProducer && number % 2 != 0) || (!isOddProducer && number % 2 == 0)) {
queue.add(number);
System.out.println("生产者" + (isOddProducer ? "1" : "2") + " 生产: " + number);
lock.notifyAll();
}
}
}
}
}
static class Consumer extends Thread {
private final Queue<Integer> queue;
private final Object lock;
private final boolean isOddConsumer;
private int sum = 0;
private final long start;
public Consumer(Queue<Integer> queue, Object lock, boolean isOddConsumer,long start) {
this.queue = queue;
this.lock = lock;
this.isOddConsumer = isOddConsumer;
this.start = start;
}
@Override
public void run() {
while (System.currentTimeMillis()-start< time.overTime) {
synchronized (lock) {
while (queue.isEmpty()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int number = queue.peek(); //获取队列头部元素
if ((isOddConsumer && number % 2 != 0) || (!isOddConsumer && number % 2 == 0)) {
queue.poll(); //移除队列的头部元素
sum += number;
System.out.println("消费者" + (isOddConsumer ? "1" : "2") + " 消费: " + number +" "+ (isOddConsumer ? "当前奇数" : "当前偶数")+" 总和: " + sum);
lock.notifyAll();
}
}
}
}
}
public static class time {
private static long overTime = 50;
}
}
运行截图: