今天通过介绍一下如何通过wait和notify来实现生产者和消费者模式。


通过synchronized同步代码块实现线程的同步操作,从而保证数据的一致性。下面具体介绍一下这个模式的实现过程。


1.首先编写一个生产者类:


public class Producer implements Runnable {
private PublicBox box;

public Producer(PublicBox box) {
this.box = box;
}

@Override
public void run() {
int i=0;
while(true){
try {
System.out.println("生产者序号:" + i);
i++;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
box.increace();
}
}
}


2.其次编写一个消费者类:


public class Consumer implements Runnable {
private PublicBox box;

public Consumer(PublicBox box) {
this.box = box;
}

@Override
public void run() {
int i=0;
while(true){
try {
System.out.println("消费者序号" + i);
i++;
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}

box.decreace();
}
}
}

3.最后编写仓库类:


public class PublicBox {
private int product = 0;

public synchronized void increace() {
while (product == 5) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

}
product++;
System.out.println("产品生产成功!目前产品的存储量:"+product);
notify();
}

public synchronized void decreace() {
while (product == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
product--;
System.out.println("产品消费成功!目前产品的存储量:"+product);
notify();
}

public static void main(String[] args) {
PublicBox box = new PublicBox();
Consumer con = new Consumer(box);
Producer pro = new Producer(box);
Thread t1 = new Thread(con);
Thread t2 = new Thread(pro);
t1.start();
t2.start();
}
}


打印出来的部分结果:


Java中通过wait和notify来实现生产者和消费者模式_i++


这个执行过程有些人可能会有些疑问,我在这里具体描述一下这整个过程是如何实现的。


在这里因为生产者所休眠的时间比消费者短,所以生产者出现的频率会比消费者高一些。


1:首先是生产者和消费者都新建了各自的序号并打印出来。


2:因为是消费者先启动的,所以首先访问decreace同步块,可是因为条件不符合所以被wait了。


3:消费者被wait之后,生产者就开始启动increace同步块生产了。生产者一生产就会调用notify方法,这个时候第二步已经被wait的线程就会被唤醒,接着执行wait之后的代码。但是这里需要注意的是并不是生产者调用notify方法,消费者就会马上被唤醒执行接下来的代码。因为唤醒和执行都需要时间,这个过程可能生产者又生成新的产品了吗,也有可能是消费者马上被执行。


4:之后的过程就是按照前面三步骤进行循环输出的。


这个模式下的生产者消费者主要是通过synchronized 同步代码块来保证product这个变量的一致性。保证product变量在多个线程的调用的过程中,线程之间不会发生互相干扰,按正确的顺序执行这些过程。