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

阻塞队列实现
EN

Stack Overflow用户
提问于 2016-05-04 19:32:36
回答 1查看 799关注 0票数 2

我刚刚用信号量实现了一个定制的阻塞队列。

由于一个我找不到的原因,当队列为空时,我的队列没有被信号量阻塞。

以下是我的实现:

代码语言:javascript
复制
package poolThread;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Semaphore;

public class MyQueue<E> {
Semaphore s = new Semaphore(0, true);
private Queue<E> queue = new LinkedList<E>(); 


public boolean isEmpty(){
    return this.queue.isEmpty();
}
public void enqueue(E e){
    queue.add(e);
    s.release();
}
public E dequeue(){
    E e = null;
    try {
        s.acquire();
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    e = queue.remove();
    return e;

}

}

你能帮我找出代码中的错误吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-04 21:42:25

这里的问题是LinkedList --它不是线程安全的。因此,即使获得了适当的许可证,remove()LinkedList的操作也会(而且会)造成麻烦。这里有一个简单的“测试用例”来显示这种行为:

代码语言:javascript
复制
MyQueue<String> x = new MyQueue<>();

ExecutorService es = Executors.newFixedThreadPool(2);
for (int j = 0; j < 2; j++)
    es.submit(() -> {
        String tn = Thread.currentThread().getName();
        for (int i = 0; i < 2; i++)
            x.enqueue("v" + i);

        for (int i = 0; i < 2; i++) 
            System.out.println(tn + " deq: " + x.dequeue());
    });

输出将类似于(您将看到由于null方法上的NoSuchElementExceptions而产生的remove s):

代码语言:javascript
复制
pool-1-thread-2 deq: v0
pool-1-thread-1 deq: null

对此,最简单的解决方案是将LinkedList替换为java.util.concurrent.ConcurrentLinkedQueue

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

https://stackoverflow.com/questions/37036461

复制
相关文章

相似问题

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