最近看到生产消费模式,顺手写了个java小测试程序。
生产 消费模式,就是一边生产,一边消费,通过共享缓存区域,生产超过缓存区域后,会唤醒消费线程起来消费,反之也一样。
这个缓存区域,我设置为100长度的List 数组。
首先我定义生产者 消费者的存储类,会对list加锁。保证线程安全,当然也可以用线程安全的集合。为了方便查看log,我选择每次执行一次生产 消费都停止1秒钟。
public class Storage {
private List<Integer> list = new ArrayList<Integer>();
public static int size = 100;
public static boolean open = true;
void product(int num) {
synchronized (list) {
while (open) {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if (list.size() + num > size) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < num; i++) {
list.add((int) (Math.random() * 100));
}
System.out.println("生产 库存总数量:" + list.size() + " 新增:" + num);
list.notify();
}
}
}
void consume(int num) {
synchronized (list) {
while(open){
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if(list.size()<=0){
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(list.size() >num){
System.out.println("size:"+list.size()+" num:"+num);
List<Integer> li=new ArrayList<Integer>();
for(int i=0;i<num;i++){
li.add(list.get(i));
}
System.out.println(li.size());
list.removeAll(li);
}else {
System.out.println("size:"+list.size()+" num:"+num);
list.clear();
}
System.out.println("消费 库存总数量:" + list.size() + " 消费:" + num);
list.notify();
}
}
}
消费线程类
public class ThreadConsumer extends Thread {
private Storage storage;
private int num;
public ThreadConsumer() {
super();
}
public ThreadConsumer(Storage storage, int num) {
super();
this.storage = storage;
this.num = num;
}
public Storage getStorage() {
return storage;
}
public void setStorage(Storage storage) {
this.storage = storage;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
storage.consume(num);
}
}
生产线程类
public class ThreadProducer extends Thread {
private Storage storage;
private int num;
public ThreadProducer() {
super();
}
public ThreadProducer(Storage storage, int num) {
super();
this.storage = storage;
this.num = num;
}
public Storage getStorage() {
return storage;
}
public void setStorage(Storage storage) {
this.storage = storage;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
storage.product(num);
}
}
在写一个测试程序:
public static void main(String[] args) {
Storage storage = new Storage();
ThreadConsumer tc1= new ThreadConsumer(storage,20);
ThreadConsumer tc2= new ThreadConsumer(storage,40);
ThreadProducer t1= new ThreadProducer(storage,20);
ThreadProducer t2= new ThreadProducer(storage,20);
ThreadProducer t3= new ThreadProducer(storage,20);
ThreadProducer t4= new ThreadProducer(storage,20);
t1.start();t2.start();t3.start();t4.start();
tc1.start();tc2.start();
}
最终log 如下:
生产 库存总数量:20 新增:20
生产 库存总数量:40 新增:20
生产 库存总数量:60 新增:20
生产 库存总数量:80 新增:20
生产 库存总数量:100 新增:20
size:100 num:40
40
消费 库存总数量:44 消费:40
size:44 num:40
40
消费 库存总数量:2 消费:40
size:2 num:40
消费 库存总数量:0 消费:40
生产 库存总数量:20 新增:20
生产 库存总数量:40 新增:20
生产 库存总数量:60 新增:20
生产 库存总数量:80 新增:20
生产 库存总数量:100 新增:20
size:100 num:20
可以看到,的确是在一边生产,每次生产超过100个后,会立即启动消费。