首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阻塞和非阻塞队列

阻塞和非阻塞队列
EN

Code Review用户
提问于 2016-10-03 05:17:33
回答 2查看 4.9K关注 0票数 2

我为阻塞和非阻塞队列实现提供了以下内容。请提出任何修改/改进/解决办法。

阻塞队列:

代码语言:javascript
复制
public class BlockingQueue<T> {
    List<T> buffer;
    private static final int MAX_QUEUE_SIZE = 100;

    public BlockingQueue() {
        buffer = new ArrayList<T>();
    }

    public void enqueue(T value) throws InterruptedException {
        synchronized(buffer) {
            while(buffer.size() >= MAX_QUEUE_SIZE) {
                buffer.wait();
            }
            buffer.add(value);
            buffer.notifyAll();
        }
    }

    public T dequeue() throws InterruptedException {
        synchronized(buffer) {
            while(buffer.size() < 1) {
                buffer.wait();
            }
            T value = buffer.remove(0);
            buffer.notifyAll();
            return value;
        }
    }

}

非阻塞队列:

代码语言:javascript
复制
public class NonBlockingQueue<T> {
    List<T> buffer;
    private static final int MAX_QUEUE_SIZE = 100;
    private AtomicBoolean mutex = new AtomicBoolean(false);

    public NonBlockingQueue() {
        buffer = new ArrayList<T>();
    }

    public void enqueue(T value) throws InterruptedException {
        while(true) {
            while(!mutex.compareAndSet(false, true)) {
                Thread.sleep(100);
            }
            if(buffer.size() < MAX_QUEUE_SIZE) {
                buffer.add(value);
                mutex.set(false);
                return;
            } else {
                mutex.set(false);
            }
        }

    }

    public T dequeue() throws InterruptedException {
        T value = null;
        while(true) {
            while(!mutex.compareAndSet(false, true)) {
                Thread.sleep(100);
            }
            if(buffer.size() > 0) {
                value = buffer.remove(0);
                mutex.set(false);
                return value;
            } else {
                mutex.set(false);
            }
        }   
    }
}

我认为非阻塞意味着线程不应该被阻塞,所以我使用了sleep方法。如果有什么问题请告诉我。

EN

回答 2

Code Review用户

发布于 2016-10-03 06:08:05

你要求批评..。

  1. 为什么要使用AtomicBoolean作为互斥对象?如果需要更复杂的行为,可以使用原始锁或Lock
  2. (几乎)任何时候在算法中使用sleep,都是错误的。在这种情况下,“错误的方式”是以上第1点的直接后果。
  3. 如果您希望在有多个生产者和消费者的情况下具有良好的性能,则应该避免执行notifyAll。例如,如果有N个消费者在等待,并且生产者添加了一个队列条目,那么所有N个消费者都会被唤醒。理想情况下,只有一个消费者应该被唤醒。
票数 2
EN

Code Review用户

发布于 2016-10-03 21:40:03

因为您将在结束时进行大量的添加,并且(特别是)从一开始就删除,所以我将使用LinkedList而不是ArrayList

我也不知道是什么使你的NonBlockingQueue非阻塞。它在睡觉,这也很好。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/143070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档