生产者和消费者 是 操作系统种比较经典的问题, 两个共用一个临界区进行互斥访问.
JAVA 中 我们采用 Runable 和 Thread 来实现 多线程编程问题;
重写 Thread 里的 Run 函数
根据分析: 用 产生随机数, 并让线程进行睡眠, 模拟真实的情况
写一个MsgQueue 队列存储信息 实现 Push 和 Pop
并用 synchronized 实现锁区 保证 函数不被打断
wait 和 notify 是 操作系统中 wait 和sigema 操作
public class MsgQueue {
private final int COUNT = 10;
private int[] Catch = new int[COUNT];
private int idex = 0;
MsgQueue(){
idex = 0;
}
public synchronized void PutMsg(int num) throws InterruptedException {
if(idex < 0 || idex > COUNT) {
wait();
}
Catch[ idex++] = num;
notify();
}
public synchronized void PopMsg() throws InterruptedException {
if( idex > COUNT || idex <0 ){
wait();
}
int num = Catch[idex--];
System.out.println("Consumer : "+ num);
notify();
}
}
对生产者 进行编写: Producer.java
import java.util.Random;
public class Producer implements Runnable {
private MsgQueue queue;
Producer(MsgQueue queue){
super();
this.queue = queue;
}
@Override
public void run() {
Random random = new Random();
while (true){
int num = random.nextInt(1000);
try {
Thread.sleep(num);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println("produce: "+num);
queue.PutMsg(num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
对消费者进行编写: Consum.java
import java.util.Random;
public class Consumer implements Runnable {
private MsgQueue queue;
Consumer(MsgQueue queue){
super();
this.queue = queue;
}
@Override
public void run() {
Random random = new Random();
while (true){
try {
int num = random.nextInt(1000);
if( num <0)
continue;
Thread.sleep(num);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
queue.PopMsg();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
1Test 测试 main 中
MsgQueue queue = new MsgQueue();
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
new Thread(producer).start();
new Thread(consumer).start();