生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。
package com.thread;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用Lock来实现生产者和消费者问题
*
* @author 刘玲
*
*/
public class ProducerConsumer {
public static void main(String[] args) {
Basket b = new Basket();
Product p = new Product(b);
Consumer c = new Consumer(b);
Consumer c1 = new Consumer(b);
new Thread(p).start();
new Thread(c).start();
new Thread(c1).start();
}
}
//馒头
class ManTou{
int id;
public ManTou(int id) {
this.id = id;
}
@Override
public String toString() {
return “ManTou”+id;
}
}
//装馒头的篮子
class Basket{
int max = 6;
LinkedList<ManTou> manTous = new LinkedList<ManTou>();
Lock lock = new ReentrantLock(); //锁对象
Condition full = lock.newCondition(); //用来监控篮子是否满的Condition实例
Condition empty = lock.newCondition(); //用来监控篮子是否空的Condition实例
//往篮子里面放馒头
public void push(ManTou m){
lock.lock();
try {
while(max == manTous.size()){
System.out.println(“篮子是满的,待会儿再生产…”);
full.await();
}
manTous.add(m);
empty.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
//往篮子里面取馒头
public ManTou pop(){
ManTou m = null;
lock.lock();
try {
while(manTous.size() == 0){
System.out.println(“篮子是空的,待会儿再吃…”);
empty.await();
}
m = manTous.removeFirst();
full.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
return m;
}
}
}
//生产者
class Product implements Runnable{
Basket basket;
public Product(Basket basket) {
this.basket = basket;
}
public void run() {
for (int i = 0; i < 40; i++) {
ManTou m = new ManTou(i);
basket.push(m);
System.out.println(“生产了”+m);
try {
Thread.sleep((int)(Math.random()*2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//消费者
class Consumer implements Runnable{
Basket basket;
public Consumer(Basket basket) {
this.basket = basket;
}
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep((int)(Math.random()*2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
ManTou m = basket.pop();
System.out.println(“消费了”+m);
}
}
}
原文博客:http://home.cnblogs.com/u/liuling/