代码很简单,就不介绍了。需要注意的是,先有生产才有消费,所以与消费者关联的semaphore计数开始为0,而与生产者关联的semaphore计数开始为1。
实现:
import java.util.concurrent.Semaphore;
/**
*
* Multithreading: consumer-producer model using semaphores
*
* @author ljs
* 2011-08-19
*
*/
public class ConsumerProducer {
//consumer-producer model
static class SharedData{
int data = 0;
Semaphore semproducer = new Semaphore(1);
//set initial count to 0, so a consumer needs to wait until data is available
Semaphore semconsumer = new Semaphore(0);
public int consume() throws InterruptedException{
try {
semconsumer.acquire();
System.out.format(" Consumed: %d%n", data);
Thread.sleep(10);
return data;
} catch (InterruptedException e) {
throw e;
} finally{
semproducer.release();
}
}
public void produce(int data) throws InterruptedException{
try {
semproducer.acquire();
this.data = data;
System.out.format("Produced: %d%n", data);
Thread.sleep(10);
} catch (InterruptedException e) {
throw e;
} finally{
semconsumer.release();
}
}
}
//consumer
static class ConsumerThread implements Runnable {
private SharedData shared;
public ConsumerThread(SharedData shared){
this.shared=shared;
}
public void run(){
for(int i=0;i<30;i++){
try {
int data = shared.consume();
//use data
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//producer
static class ProducerThread implements Runnable{
private SharedData shared;
public ProducerThread(SharedData shared){
this.shared=shared;
}
public void run(){
for(int i=0;i<30;i++){
try {
shared.produce(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws Exception {
SharedData shared = new SharedData();
Thread producer = new Thread(new ProducerThread(shared),"producer");
Thread consumer = new Thread(new ConsumerThread(shared),"consumer");
consumer.start();
producer.start();
}
}
测试输出:
Produced: 0
Consumed: 0
Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
Produced: 3
Consumed: 3
Produced: 4
Consumed: 4
Produced: 5
Consumed: 5
Produced: 6
Consumed: 6
Produced: 7
Consumed: 7
Produced: 8
Consumed: 8
Produced: 9
Consumed: 9
Produced: 10
Consumed: 10
Produced: 11
Consumed: 11
Produced: 12
Consumed: 12
Produced: 13
Consumed: 13
Produced: 14
Consumed: 14
Produced: 15
Consumed: 15
Produced: 16
Consumed: 16
Produced: 17
Consumed: 17
Produced: 18
Consumed: 18
Produced: 19
Consumed: 19
Produced: 20
Consumed: 20
Produced: 21
Consumed: 21
Produced: 22
Consumed: 22
Produced: 23
Consumed: 23
Produced: 24
Consumed: 24
Produced: 25
Consumed: 25
Produced: 26
Consumed: 26
Produced: 27
Consumed: 27
Produced: 28
Consumed: 28
Produced: 29
Consumed: 29