生产者消费者模式(Producer-Consumer)

六、生产者消费者模式(Producer-Consumer)
1、核心思想
通过管道对数据的生产者和消费者进行解耦,使二者不直接交互,从而使二者的处理速率相对来说互不影响。
2、注意通道积压
a、使用阻塞队列。
b、使用带流量控制的无界阻塞队列。
3、可复用代码

4、参考网站
Semaphore信号量控制
学习地址:http://www.cnblogs.com/whgw/archive/2011/09/29/2195555.html

Deque与LinkedBlockingDeque深入分析
学习地址:http://blog.csdn.net/vernonzheng/article/details/8267541
5、关联模式:Two-Phase模式
http://blog.csdn.net/huzhiqiangCSDN/article/details/55099853

public interface Chanel<P> {
    public P take() throws InterruptedException;
    public void put(P product) throws InterruptedException;
}

public class BlockingQueueChanel<P> implements Chanel<P> {
    //便于使用不同的队列不用改外面的代码
    private final BlockingQueue<P> queue;

    public BlockingQueueChanel(BlockingQueue<P> queue) {
        this.queue = queue;
    }

    @Override
    public P take() throws InterruptedException {
        return queue.take();
    }

    @Override
    public void put(P product) throws InterruptedException {
        queue.put(product);
    }
}

/**
* 基于Semaphore的支持流量控制的通道实现
* @author huzhiqiang
* @param


*/
public class SemaphoreBaseChanel

implements Chanel

{
//便于使用不同的队列不用改外面的代码
private final BlockingQueue

queue;
private final Semaphore semaphore;

/**
 * @param queue 阻塞队列,通常是一个无界阻塞队列
 * @param flowLimit  流量限制数
 */
public SemaphoreBaseChanel(BlockingQueue<P> queue, int flowLimit) {
    this.queue = queue;
    semaphore = new Semaphore(flowLimit);
}

@Override
public P take() throws InterruptedException {
    return queue.take();
}

@Override
public void put(P product) throws InterruptedException {
    semaphore.acquire();
    try {
        queue.put(product);
    } finally{
        semaphore.release();
    }
}

}

public class AttachmentProssor {
private final Chanel chanel = new BlockingQueueChanel(new ArrayBlockingQueue(200));

//使用了优雅终止模式,消费者实例
private final AbstractTerminatableThread indexingThread = new AbstractTerminatableThread() {
    @Override
    protected void doRun() throws Exception {
        System.out.println("consumer begin");
        File file = null;
        file = chanel.take();
        try {
            indexFile(file);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            terminationToken.reservations.decrementAndGet();
        }
    }

    private void indexFile(File file) {
        Random r = new Random();
        try {
            Thread.sleep(r.nextInt(100));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

public void init(){
    indexingThread.start();
}

public void shutdown() {
    indexingThread.terminate();
}

//生产方法
public void saveAttachment(){
    File file = new File("");
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        chanel.put(file);
        System.out.println("producer OK");
    } catch (InterruptedException e) {
    }
    indexingThread.terminationToken.reservations.incrementAndGet();
}

}

public class Main {
public static void main(String[] args) {
AttachmentProssor attachmentProssor = new AttachmentProssor();
attachmentProssor.init();

    new Thread(){
        public void run() {
            for(int i=0; i<1000; i++){
                attachmentProssor.saveAttachment();
            }
        };
    }.start();

    new Thread(){
        public void run() {
            for(int i=0; i<1000; i++){
                attachmentProssor.saveAttachment();
            }
        };
    }.start();

    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
    }
    attachmentProssor.shutdown();
}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值