需求: 多个生产者不断的生产产品,多个消费者不断的消费产品,仓库可以存放10个产品。 第一批产品需要生产20个产品,并消费完毕。
其实使用wait/notify模式实现差不多,只是使用的时候要注意防止“死锁”。
blockingQueue的实现与notify的实现效率差不多.
package ycl.learn.effective.java.thread.pc;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
public class PublicResourceBlockingQueue {
private BlockingQueue<Product> queue = new LinkedBlockingQueue<Product>(10);
private AtomicInteger index = new AtomicInteger(1);
public static final int MAX_RESOURCE = 20;
public boolean increace() {
try {
if (isComplete()) {// 生产任务完成
return false;
}
int tindex = index.getAndIncrement();
Product p = new Product(tindex);
queue.put(p);
System.out.println(Thread.currentThread() + "increace:" + tindex);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
public boolean decreace() {
try {
if (isComplete() && isEmpty()) {
return false;
}
synchronized(this){
if(!isEmpty()){
Product p = queue.take();
System.out.println(Thread.currentThread() + "decreace:" + p.index);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
/**
* 判断是否空了
*/
public boolean isEmpty() {
return queue.isEmpty();
}
/**
* 判断生产完毕
*/
public boolean isComplete() {
return index.get() > MAX_RESOURCE;
}
class Product {
public int index;
public Product(int index) {
this.index = index;
}
}
}
public static void anotherone() throws InterruptedException{
long start = System.currentTimeMillis();
PublicResourceBlockingQueue ps = new PublicResourceBlockingQueue();
CustomerB c = new CustomerB(ps);
ProductorB p = new ProductorB(ps);
Thread ct = new Thread(c,"customer0");
Thread ct1 = new Thread(c,"customer1");
Thread ct2 = new Thread(c,"customer2");
Thread ct3 = new Thread(c,"customer3");
Thread ct4 = new Thread(c,"customer4");
Thread ct5 = new Thread(c,"customer5");
Thread ct6 = new Thread(c,"customer6");
Thread pt = new Thread(p,"productor0");
Thread pt1 = new Thread(p,"productor1");
Thread pt2 = new Thread(p,"productor2");
Thread pt3 = new Thread(p,"productor3");
Thread pt4 = new Thread(p,"productor4");
Thread pt5 = new Thread(p,"productor5");
Thread pt6 = new Thread(p,"productor6");
ct.start();
ct1.start();
ct2.start();
ct3.start();
ct4.start();
ct5.start();
ct6.start();
pt.start();
pt1.start();
pt2.start();
pt3.start();
pt4.start();
pt5.start();
pt6.start();
ct.join();
ct1.join();
ct2.join();
ct3.join();
ct4.join();
ct5.join();
ct6.join();
pt.join();
pt1.join();
pt2.join();
pt3.join();
pt4.join();
pt5.join();
pt6.join();
System.out.println(System.currentTimeMillis()-start);//5531
}
Thread[productor5,5,main]increace:5
Thread[productor2,5,main]increace:3
Thread[productor3,5,main]increace:4
Thread[productor6,5,main]increace:7
Thread[productor4,5,main]increace:6
Thread[productor1,5,main]increace:2
Thread[productor0,5,main]increace:1
Thread[productor1,5,main]increace:8
Thread[productor4,5,main]increace:9
Thread[customer1,5,main]decreace:6
Thread[productor0,5,main]increace:10
Thread[customer4,5,main]decreace:5
Thread[productor4,5,main]increace:11
Thread[productor6,5,main]increace:12
Thread[customer1,5,main]decreace:7
Thread[productor0,5,main]increace:13
Thread[customer2,5,main]decreace:4
Thread[productor3,5,main]increace:14
Thread[customer5,5,main]decreace:3
Thread[productor5,5,main]increace:15
Thread[customer4,5,main]decreace:2
Thread[productor0,5,main]increace:16
Thread[customer3,5,main]decreace:1
Thread[productor2,5,main]increace:17
Thread[customer6,5,main]decreace:8
Thread[customer0,5,main]decreace:9
Thread[customer3,5,main]decreace:10
Thread[customer5,5,main]decreace:11
Thread[productor1,5,main]increace:18
Thread[customer3,5,main]decreace:12
Thread[productor4,5,main]increace:19
Thread[productor5,5,main]increace:20
Thread[customer2,5,main]decreace:13
Thread[customer5,5,main]decreace:14
Thread[productor0,5,main] exist
Thread[customer1,5,main]decreace:15
Thread[productor5,5,main] exist
Thread[productor1,5,main] exist
Thread[customer4,5,main]decreace:16
Thread[customer2,5,main]decreace:17
Thread[productor3,5,main] exist
Thread[customer6,5,main]decreace:18
Thread[customer4,5,main]decreace:19
Thread[customer1,5,main]decreace:20
Thread[productor6,5,main] exist
Thread[customer5,5,main] exist
Thread[customer3,5,main] exist
Thread[productor2,5,main] exist
Thread[customer0,5,main] exist
Thread[productor4,5,main] exist
Thread[customer6,5,main] exist
Thread[customer2,5,main] exist
Thread[customer1,5,main] exist
Thread[customer4,5,main] exist
1234
实现的逻辑少了,这里需要注意的是,queue.take(),如果queue里再也不会有数据,将会”死锁“,防止多线程同时take最后一个,这里加了把锁。