C++实现BlockingQueue

BlockingQueue在多线程开发中几乎是离不开的,它可以理解为封装好的生产者与消费者的桥梁,其实它的数据结构同前文讲的Queue一样,只是在此基础之上加入了生产与消费者模式中的wait(阻塞等待,此方法会释放锁)和唤醒(notify)
JDK中提供的常用的BlockingQueue有ArrayBlockingQueue,LinkedBlockingQueue,PriorityBlockingQueue(优先级)
STL库中queue是链表结构的队列,当然也有提供dequeue(数组结构), priority_queue,这里只写一个用queue来实现的类,其他扩展同理,其实就是一些并发锁的使用

#include 
#include 

template 
class BlockingQueue {

private:
    queue _queue;
    int capacity = INT_MAX;
    condition_variable takeVariable, putVariable;
    mutable mutex lock;

public:
    BlockingQueue();
    /**
     *
     * @param capacity 队列允许的最大值,在put时size()大于此值时,put方法将会wait
     */
    BlockingQueue(int capacity);
    /**
     * size() == 0 时会阻塞
     * @param e
     * @return -1失败, 0成功
     */
    int take(E &e);
    /**
     * size >= capacity时会阻塞
     * @param e
     * @return
     */
    int put(const E &e);

    bool empty() const;

    unsigned int size() const;

    void pop();

    E back();

    E front();
};

template 
BlockingQueue::BlockingQueue() {
}

template 
BlockingQueue::BlockingQueue(int capacity) : capacity(capacity) {
}

template 
int BlockingQueue::take(E &e) {
    unique_lock uniqueLock(lock);
    while (_queue.empty()) {
        takeVariable.wait(uniqueLock);
    }
    if (_queue.empty()) return -1;
    e = _queue.front();
    _queue.pop();
    putVariable.notify_one();
    return 0;
}

template 
int BlockingQueue::put(const E &e) {
    unique_lock uniqueLock(lock);
    while (_queue.size() >= capacity) {
        putVariable.wait(uniqueLock);
    }
    if (_queue.size() >= capacity) return -1;
    _queue.push(e);
    takeVariable.notify_one();
    return 0;
}

template 
bool BlockingQueue::empty() const {
    lock_guard lockGuard(lock);
    return _queue.empty();
}

template 
unsigned int BlockingQueue::size() const {
    lock_guard lockGuard(lock);//利用变量作用域创建加锁,析构自动解锁
    return _queue.size();
}

template 
void BlockingQueue::pop() {
    lock.lock();
    _queue.pop();
    lock.unlock();
}

template 
E BlockingQueue::back() {
    lock_guard lockGuard(lock);
    return _queue.back();
}

template 
E BlockingQueue::front() {
    lock_guard lockGuard(lock);
    return _queue.front();
}
最后附上源码https://github.com/youxiaochen/DataStructArrayLink

更多文章请关注:http://www.jianshu.com/u/b1cff340957c

你可能感兴趣的:(C++实现BlockingQueue)