生产者消费者模式,线程同步算法之一,就是一个线程生产资源,一个线程负责消耗资源。两个线程,一个叫生产者,一个叫消费者,生产者往缓存放资源,满了就不再生产,等消费者拿走资源;消费者从缓存取走资源,缓存空了就等待生产者生产资源。注意其中notify和wait成对出现且必须放在synchronize中。
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Buffer b = new Buffer();
Thread p = new Thread(new Producer(b));
Thread c = new Thread(new Consumer(b));
p.start();
c.start();
}
}
class Buffer{
int count = 0;
int[] buf = new int[10];
public Buffer() {
// TODO Auto-generated constructor stub
for (int i = 0; i < buf.length; i++) {
add(i);
}
}
public synchronized int add(int element) {
int res = -1;
if (count < buf.length && count >= 0) {//资源不满,还可以往缓存放
res = buf[count++] = element;
notify();//放完后通知消费者取
}
else if(count == buf.length){//资源满了,等消耗完再生产
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return res;//等待,生产者无需生产,每次等待返回-1
}
public synchronized int remove() {
int res = -2;
if(count > 0){//有资源,取一个后缓存有空间了,通知再生产
res = buf[--count];
notify();
}
else {//无资源,等待生产者生产
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return res;//消费者无资源消耗,需要等待返回-2
}
}
class Producer implements Runnable{
Buffer buffer;
public Producer(Buffer b) {
// TODO Auto-generated constructor stub
buffer = b;
}
public void produce(int i) {
if (buffer.add(i) == -1) {
System.out.println("buffer已经满了,不能再加");
}else{
System.out.println("Producer生产第" + buffer.add(i) + "个资源");
}
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {//有满的情况,所以未必添加100次
this.produce(i);
}
}
}
class Consumer implements Runnable{
Buffer buffer;
public Consumer(Buffer b) {
// TODO Auto-generated constructor stub
buffer = b;
}
public void consume() {
if (buffer.remove() == -2) {
System.out.println("buffer已经空了,不能在拿");
} else {
System.out.println("Consumer正在消耗第" + buffer.remove() + "个资源");
}
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {//有空的情况,所以未必拿100次
this.consume();
}
}
}