消费者生产者问题:
这个问题是一个多线程同步问题的经典案例,生产者负责生产对象,消费者负责将生成者产生的对象取出,两者不断重复此过程。这过程需要注意几个问题:
不论生产者和消费者有几个,必须保证:
1.生产者每次产出的对象必须不一样,产生的对象有且仅有出现一次;
2.消费者每次取出的对象必须不一样,取出的对象有且仅有出现一次;
3.一定是先产生该对象,然后对象才能被取出,顺序不能乱;
第一种情况:
多个生产者轮流负责生产,多个消费者负责取出。一旦生产者产生一个对象,其他生产者不能生产,只能由消费者执行取出操作;
需要的对象有商品类、消费者、生产者;
//测试类
public class ProducerConsumer {
public static void main(String[] args) {
// 定义资源对象
Resource r = new Resource();
//定义一个生产者和一个消费者
Producer p = new Producer(r);
Consumer c = new Consumer(r);
//启动四个线程,2个负责生产者,两个消费者
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(c);
Thread t4 = new Thread(c);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
//商品类
class Resource{
private String name;
private int count = 1;
private boolean flag = false;
//产生商品
public synchronized void set(String name) {
while (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name + "---" + count++;
System.out.println(Thread.currentThread().getName() + " 生产者" + this.name);
flag = true;
//唤醒所有线程
this.notifyAll();
}
//取出商品
public synchronized void out() {
while (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " 消费者________" + this.name);
flag = false;
this.notifyAll();
}
}
//定义生产者
class Producer implements Runnable{
private Resource res;
public Producer(Resource res) {
this.res = res;
}
@Override
public void run() {
while (true) {
res.set("+商品+");
}
}
}
//定义消费者
class Consumer implements Runnable{
private Resource res;
Consumer(Resource res) {
this.res = res;
}
@Override
public void run() {
while (true) {
res.out();
}
}
}
运行结果是产生一个,随即取出一个,循环往复,其运行结果的部分如下: