想想很容易,写起来却并不是很顺...磕磕巴巴写好久有木有。补充回顾不少基础知识。
参考:
一个生产者和一个消费者的情形。使用synchronized ,wait,notify。由于对于任何一方来说上锁的一定是对方,最后notify没什么问题。但多个消费者会出错。
一生产者多消费者,不过这个问题的情景生产者的情形有点微妙(等消费完了再生产这点)。
多个生产者多个消费者一种的解决方案。(concurrent的lock,Condition,await,signal)
进阶的多生产多消费者解决方案。
/**
* 生产者
*
* @author zoe
*
*/
class Productor implements Runnable {
ProductBuffer buf;
String name = "Productor";
Productor(ProductBuffer buf, String name) {
this.buf = buf;
this.name = name;
}
public Product product() {
Product p = new Product();
System.out.println(this.name + "正在生产" + p.thisnum + "号...");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
return p;
}
public void run() {
while (true) {
Product p = product();
try {
buf.add(p);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 消费者
*
* @author zoe
*
*/
class Consumer implements Runnable {
ProductBuffer buf;
String name = "Consumer";
Consumer(ProductBuffer buf, String name) {
this.buf = buf;
this.name = name;
}
public void consume(Product p) {
System.out.println(this.name + "正在消费" + p.thisnum + "号...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Product p = buf.remove();
consume(p);
Thread.sleep(new Random().nextInt(1000));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 产品
*
* @author zoe
*
*/
class Product {
static int num;
int thisnum = num;
Product() {
num++;
}
}
/**
* 产品缓冲队列
*
* @author zoe
*
*/
class ProductBuffer {
List<Product> buf = new ArrayList<Product>();
static final int MAX = 10;
// 多生产者消费者关键
Lock l = new ReentrantLock();
Condition empty = l.newCondition(); // 消费者的“空”位锁
Condition full = l.newCondition(); // 生产者的“满”位锁
synchronized boolean isFull() {
return buf.size() == MAX;
}
void add(Product p) throws Exception {
l.lock();
if (buf.size() == MAX) {
full.await();
}
buf.add(p);
System.out.println("新生产了一个!buf现有:" + buf.size() + "个\n---------");
empty.signal();
l.unlock();
}
Product remove() throws Exception {
l.lock();
if (buf.size() == 0) {
empty.await();
}
Product p = buf.remove(buf.size() - 1);
System.out.println("刚消费了一个!buf现有:" + buf.size() + "个\n---------");
full.signal();
l.unlock();
return p;
}
运行测试类
public class PAC {
public static void main(String[] args) throws Exception {
ProductBuffer buf = new ProductBuffer();
Productor p1 = new Productor(buf, "生产者a");
Productor p2 = new Productor(buf, "生产者b");
Productor p3 = new Productor(buf, "生产者c");
Consumer c = new Consumer(buf, "消费者1");
Consumer c2 = new Consumer(buf, "消费者2");
new Thread(p1).start();
new Thread(p2).start();
new Thread(p3).start();
new Thread(c).start();
new Thread(c2).start();
}
}