我刚刚使用信号量实现了自定义阻塞队列。
由于我无法找到的原因,当我的队列为空时,我的队列不会被信号量阻塞。
这是我的实施:
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;
}
}
你可以帮我在代码中找到错误吗?答案 0 :(得分:2)
这里的问题是LinkedList
- 它不是线程安全的。因此,即使正确获取许可,remove()
上的LinkedList
操作也会(并且会)引起麻烦。这是一个简单的测试案例&#34;显示行为:
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
方法NoSuchElementException
s引起的remove
}:
pool-1-thread-2 deq: v0
pool-1-thread-1 deq: null
最简单的解决方案是将LinkedList
替换为java.util.concurrent.ConcurrentLinkedQueue
。