利用 java.util.concurrent.Semaphore 实现生产者-消费者问题

JDK1.5 添加了一个新的多线程同步包 : java.util.concurrent.*。利用其中的 Semaphore 类我们可以

用 JAVA 比较简单的实现生产者-消费者问题,比之前单纯用 synchronized/notify/wait 要简单很多。

本文模拟 2 个生产者和 3 个消费者并发执行的情况,使用两个 Semaphore 分别控制缓冲区的满和空。

共享缓冲区的同步操作仍然用 synchronized 操作。

下面是源代码:

 

ExpandedBlockStart.gif 代码
package  com.zxn.test.threading;

import  java.util.ArrayList;
import  java.util.Calendar;
import  java.util.List;
import  java.util.Random;
import  java.util.concurrent.Semaphore;

/*
 * main program that tests the multiple producers and multiple consumers running in parallel.
 
*/
public   class  ProducerConsumer
{
    
//  the shared buffer for both producers and consumers
    
//  we suppose one product is a string.
     public   static  List < String >  sharedBuffer  =   new  ArrayList < String > ();
    
    
//  create 2 semaphores for the buffer full and buffer empty
    
//  if buffer is full, all producers should wait; 
    
//  if buffer is empty, all consumers should wait.
     public   static  Semaphore semaphoreBufFull  =   new  Semaphore( 5 );
    
public   static  Semaphore semaphoreBufEmpty  =   new  Semaphore( 0 );
    
    
public   static   void  main(String[] args)
    {
        
try
        {
            
//  create and start 2 producers thread
             for  (  int  i = 0 ; i < 2 ; i ++  )
            {
                Producer producer 
=   new  Producer(i);
                producer.start();
                Thread.sleep( 
1000  );
            }
            
            
//  wait for 5 seconds
            Thread.sleep(  5000  );
            
            
//  create and start 3 consumers thread
             for  (  int  i = 0 ; i < 3 ; i ++  )
            {
                Consumer consumer 
=   new  Consumer(i);
                consumer.start();
            }
        }
        
catch  (InterruptedException e)
        {
            
//  TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

/*
 * This is the producer class that extends Thread.
 
*/
class  Producer  extends  Thread
{
    
private   int  id;
    
    
public  Producer(  int  id )
    {
        
this .id  =  id;
    }
    
    
public   void  run()
    {
        
while  ( true )
        {
            
//  create a new product
            Calendar cal  =  Calendar.getInstance();
            Random rand 
=    new  Random(cal.getTimeInMillis());
            String product 
=   " NewProduct  "   +  rand.nextInt( 20 );
            
            
//  try to acquire a semaphore if the buffer is not full
             try
            {
                ProducerConsumer.semaphoreBufFull.acquire();
            }
            
catch  (InterruptedException e1)
            {
                
//  TODO Auto-generated catch block
                e1.printStackTrace();
            }

            
//  this producer thread is accessing the shared buffer...
            List < String >  buffer  =  ProducerConsumer.sharedBuffer;
            
synchronized  (buffer)
            {
                buffer.add( product );
                System.out.println(
" Producer  "   +  id  +   "  produced one new product: "   +  product  + " ! Buffer size= "   +  buffer.size()  +   " ! " );
            }
            
            
//  now we have produced a new product, let's wake up any waiting consumers
            ProducerConsumer.semaphoreBufEmpty.release();
            
            
try
            {
                Thread.sleep( 
1000  );
            }
            
catch  (InterruptedException e)
            {
                
//  TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

/*
 * This is the consumer class that extends Thread.
 
*/
class  Consumer  extends  Thread
{
    
private   int  id;
    
    
public  Consumer(  int  id )
    {
        
this .id  =  id;
    }
    
    
public   void  run()
    {
        String product 
=   null ;

        
while  ( true )
        {
            
//  try to acquire a semaphore if the buffer is not empty
             try
            {
                ProducerConsumer.semaphoreBufEmpty.acquire();
            }
            
catch  (InterruptedException e1)
            {
                
//  TODO Auto-generated catch block
                e1.printStackTrace();
            }

            
//  this consumer thread is accessing the shared buffer...
            List < String >  buffer  =  ProducerConsumer.sharedBuffer;
            
synchronized  (buffer)
            {
                
int  count  =  buffer.size();
                product 
=  buffer.get( count - 1  );
                buffer.remove( count
- 1  );
                System.out.println(
" Consumer  "   +  id  +   "  consumed one product: "   +  product  + " ! " );
            }
            
            
//  now we have consumed a product, let's wake up any waiting producers
            ProducerConsumer.semaphoreBufFull.release();
            
            
try
            {
                Thread.sleep( 
1000  );
            }
            
catch  (InterruptedException e)
            {
                
//  TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

 

 运行该代码,将打印如下输出:

Producer 0 produced one new product:NewProduct 9! Buffer size=1!
Producer 1 produced one new product:NewProduct 13! Buffer size=2!
Producer 0 produced one new product:NewProduct 19! Buffer size=3!
Producer 1 produced one new product:NewProduct 5! Buffer size=4!
Producer 0 produced one new product:NewProduct 6! Buffer size=5!
Consumer 0 consumed one product:NewProduct 6!
Producer 1 produced one new product:NewProduct 15! Buffer size=5!
Consumer 1 consumed one product:NewProduct 15!
Producer 0 produced one new product:NewProduct 16! Buffer size=5!
Consumer 2 consumed one product:NewProduct 16!
Consumer 2 consumed one product:NewProduct 5!
Consumer 0 consumed one product:NewProduct 19!
Producer 0 produced one new product:NewProduct 9! Buffer size=3!
Producer 1 produced one new product:NewProduct 9! Buffer size=4!
Consumer 1 consumed one product:NewProduct 9!
Consumer 2 consumed one product:NewProduct 9!
Consumer 0 consumed one product:NewProduct 13!
Consumer 1 consumed one product:NewProduct 9!
Producer 1 produced one new product:NewProduct 19! Buffer size=1!
Producer 0 produced one new product:NewProduct 19! Buffer size=2!
Consumer 0 consumed one product:NewProduct 19!
Consumer 2 consumed one product:NewProduct 19!
Producer 0 produced one new product:NewProduct 14! Buffer size=1!
Producer 1 produced one new product:NewProduct 14! Buffer size=2!
Consumer 1 consumed one product:NewProduct 14!
Consumer 0 consumed one product:NewProduct 14!
Producer 1 produced one new product:NewProduct 2! Buffer size=1!
Consumer 1 consumed one product:NewProduct 2!
Producer 0 produced one new product:NewProduct 2! Buffer size=1!
Consumer 2 consumed one product:NewProduct 2!
Producer 1 produced one new product:NewProduct 14! Buffer size=1!
Consumer 1 consumed one product:NewProduct 14!

 

可以看出,程序开始时,两个生产者线程共生产了 5 个产品。之后 3 个消费者启动后,开始消费产品。

这5 个线程并发运行。一段时间之后,我们可以看到 buffer 的 size 趋向于 1,这是因为消费者比

生产者多一个的缘故。

转载于:https://www.cnblogs.com/zxnblake/archive/2010/06/28/1767098.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值