生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况:
存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品。互相等待,从而发生死锁。
package 生产着消费者;
public class Basket1 {
private Object[] arr;
public Basket1() {
arr = new Object[5];
}
public synchronized void produce(Object obj) {
int pos = -1;
while (true) {
pos = indexOfNull();
if (pos == -1)
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
else
break;
}
System.out.println(Thread.currentThread() + "生产了一个数据:" + obj);
arr[pos] = obj;
this.notifyAll();
}
private synchronized int indexOfNull() {
int res = -1;
for (int i = 0; i < arr.length; i++) {
Object tmp = arr[i];
if (tmp == null) {
res = i;
break;
}
}
return res;
}
public synchronized void consume() {
int pos = -1;
while (true) {
pos = indexOfNonNull();
if (pos == -1) {
try {
this.wait();
} catch (Exception e) {
e.printStackTrace();
}
} else
break;
}
System.out.println(Thread.currentThread() + "消费了一个数据:" + arr[pos]);
arr[pos] = null;
this.notifyAll();
}
private synchronized int indexOfNonNull() {
int res = -1;
for (int i = 0; i < arr.length; i++) {
Object tmp = arr[i];
if (tmp != null) {
res = i;
break;
}
}
return res;
}
}
package 生产着消费者;
public class Consumer implements Runnable {
private Basket1 resource = null;
public Consumer(Basket1 resource) {
this.resource = resource;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
resource.consume();
}
}
}
package 生产着消费者;
import java.util.Date;
public class Producter implements Runnable {
private Basket1 resource = null;
public Producter(Basket1 resource2) {
this.resource = resource2;
}
public void run() {
for (int i = 0; i < 20; i++) {
Object obj = new Date();
resource.produce(obj);
}
}
}
package 生产着消费者;
public class Test {
public static void main(String[] args) {
Basket1 resource = new Basket1();
new Thread(new Producter(resource)).start();
new Thread(new Consumer(resource)).start();
}
}
运行结果: