生产者消费者模式是并发、多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据。
下面就利用生产馒头和消费馒头来简单实现,代码来自尚学堂《实战java程序设计》,代码简单易懂。
public class TestProduce {
public static void main(String[] args) {
SyncStack sStack = new SyncStack();// 定义缓冲区对象;
Shengchan sc = new Shengchan(sStack);// 定义生产线程;
Xiaofei xf = new Xiaofei(sStack);// 定义消费线程;
sc.start();
xf.start();
}
}
class Mantou {// 馒头
int id;
Mantou(int id) {
this.id = id;
}
}
class SyncStack {// 缓冲区(相当于:馒头筐)
int index = 0;
Mantou[] ms = new Mantou[10];
public synchronized void push(Mantou m) {
while (index == ms.length) {//说明馒头筐满了
try {
this.wait();//wait后,线程会将持有的锁释放,进入阻塞状态;这样其它需要锁的线程就可以获得锁;
//这里的含义是执行此方法的线程暂停,进入阻塞状态,等消费者消费了馒头后再生产。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();// 唤醒在当前对象等待池中等待的第一个线程。notifyAll叫醒所有在当前对象等待池中等待的所有线程。
// 如果不唤醒的话。以后这两个线程都会进入等待线程,没有人唤醒。
ms[index] = m;
index++;
}
public synchronized Mantou pop() {
while (index == 0) {//如果馒头筐是空的;
try {
this.wait();//如果馒头筐是空的,就暂停此消费线程(因为没什么可消费的嘛)。
//等生产线程生产完再来消费;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
index--;
return ms[index];
}
}
class Shengchan extends Thread {// 生产者线程
SyncStack ss = null;
public Shengchan(SyncStack ss) {
this.ss = ss;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("生产馒头:" + i);
Mantou m = new Mantou(i);
ss.push(m);
}
}
}
class Xiaofei extends Thread {// 消费者线程;
SyncStack ss = null;
public Xiaofei(SyncStack ss) {
this.ss = ss;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
Mantou m = ss.pop();
System.out.println("消费馒头:" + i);
}
}
}