我正在努力让我的班级成为队列,如果我有两个线程,一个添加,另一个删除元素 - 他们可以在同时。目前有一个被阻止,因为线程正在竞争相同的锁对象。
public class Queue {
private Cell head, tail;
public synchronized void add(Object o){
Cell c = new Cell(o);
if (tail == null) { head = c; }
else { tail.next = c; }
c.next = null;
tail = c;
notifyAll();
}
public synchronized Object remove()
throws InterruptedException {
while (head == null){
wait();
}
Cell c = head;
head = head.next;
if (head == null){ tail = null; };
return c.contents;
}
}
class Cell {
Cell next;
Object contents;
public Cell(Object o) { contents = o; }
}
主要
public static void main(String[] args) throws InterruptedException {
Queue q = new Queue();
Thread thr = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++)
q.add(new Integer(i));
}
});
Thread thr1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++)
try {
q.remove();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
thr.start();
thr1.start();
}
答案 0 :(得分:1)
标准同步技术无法满足您的要求。也就是说,队列的并发更新。这是因为当一个线程获取队列上的锁时,另一个线程就无法获取队列上的锁,因此无法继续。
为了实现对队列的并发更新,您必须实现的技术称为 lock stripping 。这就是ConcurrentHashMap
等并发集合实现并发读写的方式。实现锁定剥离并非易事。
您需要问问自己,与选择ConcurrentLinkedDeque
等JDK集合相比,实现带锁定剥离的自定义集合是否更容易。