多线程之间的数据通讯方法
生产者消费者模式
生产/消费者问题是个非常典型的多线程问题,涉及到的对象包括生产者、消费者、仓库和产品。他们之间的关系如下:
- 生产者仅仅在仓储未满时候生产,仓满则停止生产。
- 消费者仅仅在仓储有产品时候才能消费,仓空则等待。
- 当消费者发现仓库没产品可消费时候会通知生产者生产。
- 生产者在生产出可消费产品时候,应该通知等待的消费者去消费。
编码实现
仓库类,产品就是仓库的属性data
//临界资源
public class Basket {
private volatile Object data;
//生产者向仓库中存放数据
public synchronized void product(Object data) {
//如果仓库中有数据,则生产者进入阻塞等待,直到其它线程唤醒
while(this.data!=null)
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
//如果没有数据则进行生产操作
this.data=data;
System.out.println(Thread.currentThread().getName()+"生产了一个日期"+this.data);
this.notifyAll();//唤醒在当前对象上处于wait的所有线程
}
//消费者从仓库中消费数据
public synchronized void consume() {
//如果仓库中没有数据,则消费者进入阻塞等待,直到其它线程唤醒
while(this.data==null)
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
//如果有数据data!=null,则执行消费操作
System.out.println(Thread.currentThread().getName()+"消费了一个数据"+this.data);
this.data=null;
this.notifyAll(); //唤醒在当前对象上处于wait的所有线程
}
}
生产者线程负责生产产品,并和消费者共享仓库
public class Producer extends Thread {
private Basket basket;
//通过构造器传入对应的basket对象
public Producer(Basket basket) {
this.basket=basket;
}
@Override
public void run() {
//生产20次日期对象
for(int i=0;i<20;i++) {
Object data=new Date(); //生产者生产的具体产品
basket.product(data);
}
}
}
消费者线程负责消费产品,并和生产者共享仓库
public class Consumer extends Thread {
private Basket basket;
public Consumer(Basket basket) {
this.basket = basket;
}
@Override
public void run() {
// 消费20次日期对象
for (int i = 0; i < 20; i++) {
basket.consume();
}
}
}