线程通信的应用:经典例题: 生产者/消费者问题
- 生产者将产品交给店员,而消费者从店员处取走产品,店员一次只能持有固定数量的产品,如果店员试图生产更多数量的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会通知消费者让他等一下,等到店中有产品时再来取走
- 分析:
- 是否多线程的问题 ? 是,生产者线程,消费者问题
- 是否有线程安全问题 ? 是,店员或者产品的数量
public class ProducterAndConsumers {
public static void main(String[] args) {
Clerk clerk=new Clerk();
Producer producer=new Producer(clerk);
producer.setName("生产者一:");
Consumer consumer=new Consumer(clerk);
consumer.setName("消费者一:");
producer.start();
consumer.start();
}
}
class Clerk{
private int things=0;//产品
// 生产产品
public synchronized void produceProduct() {
if(things<20){
things++;
System.out.println(Thread.currentThread().getName()+"开始生产第"+things+"个产品");
notify();
}else{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 消费产品
public synchronized void ConsumeProduct() {
if(things>0){
System.out.println(Thread.currentThread().getName()+"开始消费第"+things+"个产品");
things--;
notify();
}else{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer extends Thread{
private Clerk clerk;
public Producer(Clerk clerk){
this.clerk=clerk;
}
@Override
public void run() {
System.out.println(getName()+"开始生产产品.....");
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.produceProduct();
}
}}
class Consumer extends Thread{
private Clerk clerk;
public Consumer(Clerk clerk){
this.clerk=clerk;
}
@Override
public void run() {
System.out.println(getName()+"消费者开始消费产品.....");
while(true){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.ConsumeProduct();
}
}
}