public
class
Producer
extends
Thread
{
privateProductListproducts=ProductList.getInstance();

publicvoidrun(){
inti=0;

while(i<=20){
synchronized(products){//Getlockonproductlist
if(products.isFull()){
System.out.println("Listisfull");
products.notify();//Releasethelock
}else{
Productproduct=newProduct(i++);//Produceaproduct
products.put(product);
System.out.println("Producedproduct"+product.getId());
products.notify();//Releaselock
}
}//Releasethelock
}
}
}
public
class
Consumer
extends
Thread
{
ProductListproducts=ProductList.getInstance();

publicvoidrun(){
while(true){
synchronized(products){
try{
products.wait();//Waitforlock
Productproduct=null;
if(!(products.isEmpty()))
product=products.take();
else
System.out.println("Listisempty");
System.out.println("Consumedproduct"+product.getId());//Getthelock
}catch(InterruptedExceptionex){
ex.printStackTrace();
}
}//Releasethelock
}
}
}
import
java.util.ArrayList;
import
java.util.List;

public
class
ProductList
{
privatestaticProductListinstance=newProductList();
privateList<Product>products;//Adapterpattern
publicstaticfinalintSIZE=10;

privateProductList(){
products=newArrayList<Product>(SIZE);
}

publicstaticProductListgetInstance(){//Singletonpattern
returninstance;
}

publicbooleanisFull(){
returnproducts.size()==SIZE;
}

publicvoidput(Productproduct){
products.add(product);
}

publicProducttake(){
returnproducts.remove(0);
}

publicbooleanisEmpty(){
returnproducts.isEmpty();
}
}
public
class
Product
{
privateintid;

publicProduct(intid){
this.id=id;
}

publicintgetId(){
returnid;
}
}
public
class
Main
{
publicstaticvoidmain(String[]args){
Producerp=newProducer();
Consumerc=newConsumer();

p.start();
c.start();
}
}
虽然Java对信号量及原语做了更高层次的封装(wait()、notify()、notifyAll()、synchronized{}),但看完上述代码还是觉得有点麻烦,于是JDK 5在原先collection框架的基础上增加了java.util.concurrent包,封装了许多用于线程并发操作的数据结构和操作。其中的BlockingQueue接口就是封装了一个阻塞队列的接口,具体地说就是实现了一个用于消费者(多个)和生产者(多个)交换产品的中介,生产者线程在队列满时阻塞,消费者线程在队列空时阻塞,当然在没有得到锁之前两类线程均会阻塞。详细信息可以参考Java Doc。下面用BlockingQueue实现P-C模型:
class
Producer
implements
Runnable
{
privatefinalBlockingQueuequeue;
Producer(BlockingQueueq){queue=q;}
publicvoidrun(){
try{
while(true){queue.put(produce());}
}catch(InterruptedExceptionex){
handle
}
}
Objectproduce(){
}
}

class
Consumer
implements
Runnable
{
privatefinalBlockingQueuequeue;
Consumer(BlockingQueueq){queue=q;}
publicvoidrun(){
try{
while(true){consume(queue.take());}
}catch(InterruptedExceptionex){
handle
}
}
voidconsume(Objectx){
}
}

class
Setup
{
voidmain(){
BlockingQueueq=newSomeQueueImplementation();
Producerp=newProducer(q);
Consumerc1=newConsumer(q);
Consumerc2=newConsumer(q);
newThread(p).start();
newThread(c1).start();
newThread(c2).start();
}
}
可以看出代码中没有出现wait()或notify()之类的原语操作,这些操作由concurrent框架负责封装。更全面的讨论可以参考 《驯服 Tiger: 并发集合》(IBM)

































































































虽然Java对信号量及原语做了更高层次的封装(wait()、notify()、notifyAll()、synchronized{}),但看完上述代码还是觉得有点麻烦,于是JDK 5在原先collection框架的基础上增加了java.util.concurrent包,封装了许多用于线程并发操作的数据结构和操作。其中的BlockingQueue接口就是封装了一个阻塞队列的接口,具体地说就是实现了一个用于消费者(多个)和生产者(多个)交换产品的中介,生产者线程在队列满时阻塞,消费者线程在队列空时阻塞,当然在没有得到锁之前两类线程均会阻塞。详细信息可以参考Java Doc。下面用BlockingQueue实现P-C模型:








































可以看出代码中没有出现wait()或notify()之类的原语操作,这些操作由concurrent框架负责封装。更全面的讨论可以参考 《驯服 Tiger: 并发集合》(IBM)