A peek**,LinkedList ** .方法**
不幸的是,我需要一个线程安全的LinkedList. 。因此,我的第一个想法是将其包装如下:
List<Object> list = Collections.synchronizedList(new LinkedList<>());但是,由于List接口不包含peek或pop方法。当然这不管用。
或者,我可以在整个代码中使用synchronized(list)块。这就是该走的路吗?
有什么我忽略的解决办法吗?
编辑:
使用LinkedList有很多原因。我看到有些人在提议其他的收藏。因此,这里遵循简短的要求,这将导致我决定使用LinkedList。
更多背景资料:
peek编辑和验证。如果验证失败,则项目需要保留在列表中。发布于 2015-11-20 16:59:35
如果您需要peek来工作,那么做一个同步包装器可能是不够的,所以您必须显式地编写synchronized。
这与其说是编写包装器的问题,不如说是peek方法的语义问题。与表示单个操作的pop方法不同,peek方法通常用于由peek-ing组成的多组分操作中,然后根据peek返回的内容执行其他操作。
如果在包装器中同步,结果将与手动编写此代码相同:
String s;
synchronized(list) {
s = list.peek();
}
// <<== Problem ==>>
if (s != null) {
synchronized(list) {
s = list.pop();
}
}这出现了一个问题,因为在某个时刻,您的列表可以在peek和pop之间进行更改(上面的代码中的这个位置被标记为" problem ")。
进行检查和修改的正确方法是在单个synchronized块中进行检查和修改,即
synchronized(list) {
String s = list.peek();
if (s != null) {
s = list.pop();
}
}但是,这不能在简单的包装器中完成,因为两个列表操作是在一个synchronized块中执行的。
您可以通过构建自己的数据结构来封装一个synchronized,并提供在同步块中执行所有测试和修改操作的操作,从而避免在多个地方编写LinkedList<T>。然而,这并不是一个简单的问题,因此您最好以一种可以与预定义的并发容器一起工作的方式更改算法。
发布于 2015-11-20 17:01:14
您想要的是并发的Queue。LinkedList实现了List、Deque和Queue。Queue是给予它FIFO (添加回来,从前面删除)语义与peek和pop。
LinkedBlockingQueue可以有界,这是您的标准之一。还有其他几个并发队列和Deques可供选择。
https://stackoverflow.com/questions/33831871
复制相似问题