生产者、消费者问题:
生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,
店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,
如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中
有产品了再通知消费者来取走产品。
分析: 线程 操作 资源类
- 是否是一个多线程问题?是!生产者 、消费者
- 是否有线程安全问题呢?有!
- 是否有共享数据?有!产品数量
- 是否需要使用同步机制?是!
- 是否涉及到线程通信?是!
public class ConsumerProducerTest {
/**
* @Title: main
* @Description: TODO
* @param @param args
* @return void
* @throws
*/
public static void main(String[] args) {
//
Clerk clerk = new Clerk(20);
Producer producer = new Producer(clerk);
Consumer consumer1 = new Consumer(clerk);
Consumer consumer2 = new Consumer(clerk);
producer.setName("生产者");
consumer1.setName("消费者1");
consumer2.setName("消费者2");
//启动线程
producer.start();
consumer1.start();
consumer2.start();
}
}
/**
*
* @ClassName: Consumer
* @Description: 消费者类
* @author xiaow
* @date 2020-03-11 21:16
*
*/
class Consumer extends Thread{
private Clerk clerk;
/**
* Consumer.
*
* @param clerk
*/
public Consumer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
System.out.println("================消费者消费产品==================");
while(true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clerk.minusProduct();
}
}
}
/*
*
* @ClassName: Producer
* @Description: 生产者生产产品
* @author xiaow
* @date 2020-03-11 21:16
*
*/
class Producer extends Thread{
private Clerk clerk;
/**
* Producer.
*
* @param clerk
*/
public Producer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
System.out.println("================生产者生产产品==================");
while(true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clerk.addProduct();
}
}
}
/**
*
* @ClassName: Clerk
* @Description: 产品资源类
* @author xiaow
* @date 2020-03-11 21:16
*
*/
class Clerk{
private int productNum = 0; //产品数量
/**
*
* @Title: addProduct
* @Description: 生产产品
* @param
* @return void
* @throws
*/
public synchronized void addProduct() {
if (productNum < 20) {
productNum++;
System.out.println(Thread.currentThread().getName()+"生产了第"+productNum+"个产品");
//唤醒消费者
this.notifyAll();
}else {
try {
//产品过多,等待,生产者线程阻塞
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* Clerk.
*
* @param productNum
*/
public Clerk(int productNum) {
this.productNum = productNum;
}
/**
*
* @Title: minusProduct
* @Description: 消费产品
* @param
* @return void
* @throws
*/
public synchronized void minusProduct() {
if (productNum > 0) {
System.out.println(Thread.currentThread().getName()+"消费了第"+productNum+"个产品");
productNum--;
//唤醒生产者
this.notifyAll();
}else {
try {
//产品数量不够,等待,消费者线程阻塞
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}