使用Semaphore实现阻塞队列

package semaphore;

import java.util.concurrent.Semaphore;

public class BlockingQvsSemaphore {

    /** 
     * @Title: 使用Semaphore实现阻塞队列
     * @Description: 使用只有1个许可的
     * @param @param args    设定文件 
     * @return void    返回类型 
     * @throws 
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Thread(new Producer()).start();  
        new Thread(new BConsumer()).start();
        new Thread(new BConsumer()).start();
    }

}
/**
 * 信号类
 * */
class Signs{  
    static Semaphore empty=new Semaphore(10); //信号量:记录仓库空的位置  
    static Semaphore full=new Semaphore(0);   //信号量:记录仓库满的位置  
    static Semaphore mutex=new Semaphore(1);  //临界区互斥访问信号量(二进制信号量),相当于互斥锁。  
} 
/**
 * 生产者
 * */
class Producer implements Runnable{  
    @SuppressWarnings("static-access")
    public void run() {
        try {
            while (true) {
                Signs.empty.acquire(); // 递减仓库空信号量,将消费计数器减1
                Signs.mutex.acquire(); // 进入临界区
                System.out.println("生成一个产品放入仓库");
                Signs.mutex.release(); // 离开临界区
                Signs.full.release(); // 递增仓库满信号量,将库存计数器加1
                Thread.currentThread().sleep(100);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
/**
 * 消费者
 * */
class BConsumer implements Runnable{  
    @SuppressWarnings("static-access")
    public void run() {
        try {
            while (true) {
                Signs.full.acquire(); // 递减仓库满信号量,将库存计数器减1
                Signs.mutex.acquire();
                System.out.println("从仓库拿出一个产品消费");
                Signs.mutex.release();
                Signs.empty.release(); // 递增仓库空信号量,将消费计数器加1
                Thread.currentThread().sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }  
   
}

感觉注释不太容易理,下面给个自己的理解的例子,其实是一模一样的

package semaphore;

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

public class SemaphoreBlockingQueue {

    /** 
     * @Title: 使用Semaphore实现简单的阻塞队列 
     * @Description: 
     * @param @param args    设定文件 
     * @return void    返回类型 
     * @throws 
     */
    public static void main(String[] args) {
        SemaphoreQueue queue = new SemaphoreQueue(20);
        //开始生产
        Productor productor = new Productor(queue);
        productor.setName("生产者");
        productor.start();
        //开始消费
        Cousumertor c1 = new Cousumertor(queue);
        c1.setName("消费者-c1");
        Cousumertor c2 = new Cousumertor(queue);
        c2.setName("消费者-c2");
        c1.start();
        c2.start();
    }

}
/**
 * 队列
 * mutex相当于锁,用于控制非线程安全的valueList的操作
 * */
class SemaphoreQueue{
    private List valueList;
    private Semaphore putActionNum;//可以进行put操作的许可数量
    private Semaphore getActionNum;//可以进行take操作的许可数量
    private Semaphore mutex;
    
    public SemaphoreQueue(int capacity){
        putActionNum = new Semaphore(capacity);//维护队列大小
        getActionNum = new Semaphore(0);//初始化时,队列为空,put操作许可数量为0
        mutex = new Semaphore(1);//用于保护非线程安全的valueList操作,用于并发生产时控制
        valueList = new ArrayList(capacity);
    }
    
    
    public void put(Integer message){
        try {
            putActionNum.acquire();//put操作许可减1
            mutex.acquire();
            valueList.add(message);
            mutex.release();
            getActionNum.release();//get操作许可加1
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public Integer take(){
        Integer message=null;
        try {
            getActionNum.acquire();//get操作许可减1
            mutex.acquire();
            if(valueList.size()>0){
                message = valueList.get(0);
                valueList.remove(0);
            }else{
                return null;
            }
            mutex.release();
            putActionNum.release();//put操作许可加1
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return message;
    }
}
/**
 * 生产者
 * */
class Productor extends Thread{
    SemaphoreQueue queue;
    public Productor(SemaphoreQueue queue){
        this.queue = queue;
    }
    @SuppressWarnings("static-access")
    public void run(){
        int i=0;
        try
        {
            while(true){
                i++;
                Integer message = new Integer(i);
                queue.put(message);
                if(i%20==0){
                    System.out.println("======== "+this.getName()+" 累计生产了 "+i+" 条消息  =======");
                    Thread.currentThread().sleep(1000);
                }
                
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
/**
 * 消费者
 * */
 class Cousumertor extends Thread{
     SemaphoreQueue queue;
     public Cousumertor(SemaphoreQueue queue){
         this.queue = queue;
     }
     @SuppressWarnings("static-access")
    public void run(){
         try{
             while(true){
                 Integer message = queue.take();
                 if(message!=null){
                     System.out.println("======== "+this.getName()+" 消费消息:"+message+" =======");
                 }
                 Thread.currentThread().sleep(100);
             }
         }catch(Exception e){
             e.printStackTrace();
         }
     }
 }


转载于:https://my.oschina.net/sharkbobo/blog/270347

你可能感兴趣的:(使用Semaphore实现阻塞队列)