生产者消费者程序可使用多种方法实现,有使用synchronized关键字,Lock对象,semaphore同步工具。今天用synchronized实现时碰到两个问题,一个是报 IllegalMonitorStateException ,另一个是碰到死锁。死锁暂时解决不了。
生产者消费者有一个生产者一个消费者及多个生产者多个消费者。
一个生产者一个消费者
package cn.bj.demo.spring.javaevent.pc.sync;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 生产者消费者,假设有个传送带,生产者往传送带上放产品,消费者从传送带上取产品
*
* */
public class ProducerAndConsumer {
private static int MAX_SIZE = 2; //传送带上最多能放产品数
private List<Product> products = null; //传送带
private ProducerTask pTask; //生产者任务
private ConsumerTask cTask; //消费者任务
private Producer p; //生产者
public ProducerAndConsumer() {
p = new Producer();
products = new ArrayList<Product>();
pTask = new ProducerTask(p, products);
cTask = new ConsumerTask(products);
Thread pThread = new Thread(pTask);
pThread.setName("producer thread");
pThread.start();
Thread cThread = new Thread(cTask);
cThread.setName("consumer thread");
cThread.start();
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("construct is over");
}
public static void main(String[] args) {
ProducerAndConsumer pac = new ProducerAndConsumer();
}
class ProducerTask implements Runnable {
private Producer producer;
private List<Product> products;
public ProducerTask() {
// TODO Auto-generated constructor stub
}
public ProducerTask(Producer producer, List<Product> products) {
this.producer = producer;
this.products = products;
}
@Override
public void run() {
synchronized(products) {
while (true) {
try {
while (products.size() >= MAX_SIZE) {
products.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
while (products.size() < MAX_SIZE) {
Product p = producer.produce();
products.add(p);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
products.notify();
}
}
}
}
}
class ConsumerTask implements Runnable {
private List<Product> products;
public ConsumerTask(List<Product> products) {
this.products = products;
}
@Override
public void run() {
synchronized(products) {
while (true) {
try {
while (products.size() < MAX_SIZE) {
products.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
while (products.size() > 0) {
Product p = products.remove(0);
System.out.println(Thread.currentThread().getName() + " consummed a product, id = " + p.getId());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
products.notify();
}
}
}
}
}
class Producer {
public Product produce() {
Product p = new Product();
System.out.println("produced product, id = " + p.getId());
return p;
}
}
}
多生产者多消费者
package cn.bj.demo.spring.javaevent.pc.sync;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 多个生产者,多个消费者
*
* */
public class MultiProducerAndMultiConsumer {
private static int MAX_SIZE = 10;
private List<Product> products = null; //产品容器
private List<ProducerTask> pTasks; //生产者任务组
private List<ConsumerTask> cTasks; //消费者任务组
private Object pLock; //生产者锁
private Object cLock; //消费者锁
private Producer p; //生产者
public MultiProducerAndMultiConsumer() {
p = new Producer();
pLock = new Object();
cLock = new Object();
pTasks = new ArrayList<ProducerTask>();
cTasks = new ArrayList<ConsumerTask>();
String pName = "product thread, number";
String cName = "consumer thread, number";
products = new ArrayList<Product>(10);
for (int i = 0; i < 10; i ++) {
ProducerTask pTask = new ProducerTask(p, products);
pTasks.add(pTask);
Thread pThread = new Thread(pTask);
pThread.setName(pName + i);
pThread.start();
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for (int i = 0; i < 10; i++) {
ConsumerTask cTask = new ConsumerTask(products);
cTasks.add(cTask);
Thread cThread = new Thread(cTask);
cThread.setName(cName + i);
cThread.start();
}
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("construct is over");
}
public static void main(String[] args) {
MultiProducerAndMultiConsumer pac = new MultiProducerAndMultiConsumer();
}
class ProducerTask implements Runnable {
private Producer producer;
private List<Product> products;
public ProducerTask() {
// TODO Auto-generated constructor stub
}
public ProducerTask(Producer producer, List<Product> products) {
this.producer = producer;
this.products = products;
}
@Override
public void run() {
while (true) {
synchronized(pLock) {
try {
while (products.size() == MAX_SIZE) {
pLock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
Product p = producer.produce();
products.add(p);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (products.size() == 3) {
synchronized(cLock) {
System.out.println("notify all consumer");
cLock.notifyAll();
}
}
}
}
}
}
class ConsumerTask implements Runnable {
private List<Product> products;
public ConsumerTask(List<Product> products) {
this.products = products;
}
@Override
public void run() {
while (true) {
synchronized(cLock) {
try {
while (products.size() == 0) {
cLock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
Product p = products.remove(0);
System.out.println("--------" + Thread.currentThread().getName() + " consummed a product, id = " + p.getId());
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(pLock) {
if (products.size() == 3) {
System.out.println("notify all producer");
pLock.notifyAll();
}
}
}
}
}
}
class Producer {
public Product produce() {
Product p = new Product();
System.out.println(Thread.currentThread().getName() + " produced product, id = " + p.getId());
return p;
}
}
}
package cn.bj.demo.spring.javaevent.pc.sync;
public class Product {
public static int serialNo = 0;
private Integer id;
protected Product(Integer id) {
setId(id);
}
public Product() {
this.id = serialNo ++;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
if (id.intValue() < 0) {
throw new RuntimeException(id + "can not be negative");
}
this.id = id;
}
}
上边多生产者多消费者代码里因ProducerTask和ConsumerTask中获取锁的顺序不同,会导致死锁。暂时不处理。。。