首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步LinkedList - peek

同步LinkedList - peek
EN

Stack Overflow用户
提问于 2015-11-20 16:46:31
回答 2查看 10.8K关注 0票数 5

A peek**LinkedList ** .方法**

不幸的是,我需要一个线程安全的LinkedList. 。因此,我的第一个想法是将其包装如下:

代码语言:javascript
复制
List<Object> list = Collections.synchronizedList(new LinkedList<>());

但是,由于List接口不包含peekpop方法。当然这不管用。

或者,我可以在整个代码中使用synchronized(list)块。这就是该走的路吗?

有什么我忽略的解决办法吗?

编辑:

使用LinkedList有很多原因。我看到有些人在提议其他的收藏。因此,这里遵循简短的要求,这将导致我决定使用LinkedList

更多背景资料:

  • 我使用的是LinkedList,因为这些商品需要订购。
  • 项目应以非阻塞方式添加。
  • 物品被添加在后面;从前面移走。
  • 在删除第一项之前,首先需要对其进行peek编辑和验证。如果验证失败,则项目需要保留在列表中。
  • 只有当验证成功完成时,第一项才会被删除。
  • 队列需要最大大小(以避免内存问题)。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-20 16:59:35

如果您需要peek来工作,那么做一个同步包装器可能是不够的,所以您必须显式地编写synchronized

这与其说是编写包装器的问题,不如说是peek方法的语义问题。与表示单个操作的pop方法不同,peek方法通常用于由peek-ing组成的多组分操作中,然后根据peek返回的内容执行其他操作。

如果在包装器中同步,结果将与手动编写此代码相同:

代码语言:javascript
复制
String s;
synchronized(list) {
    s = list.peek();
}
// <<== Problem ==>>
if (s != null) {
    synchronized(list) {
        s = list.pop();
    }
}

这出现了一个问题,因为在某个时刻,您的列表可以在peekpop之间进行更改(上面的代码中的这个位置被标记为" problem ")。

进行检查和修改的正确方法是在单个synchronized块中进行检查和修改,即

代码语言:javascript
复制
synchronized(list) {
    String s = list.peek();
    if (s != null) {
        s = list.pop();
    }
}

但是,这不能在简单的包装器中完成,因为两个列表操作是在一个synchronized块中执行的。

您可以通过构建自己的数据结构来封装一个synchronized,并提供在同步块中执行所有测试和修改操作的操作,从而避免在多个地方编写LinkedList<T>。然而,这并不是一个简单的问题,因此您最好以一种可以与预定义的并发容器一起工作的方式更改算法。

票数 5
EN

Stack Overflow用户

发布于 2015-11-20 17:01:14

您想要的是并发的QueueLinkedList实现了ListDequeQueueQueue是给予它FIFO (添加回来,从前面删除)语义与peek和pop。

LinkedBlockingQueue可以有界,这是您的标准之一。还有其他几个并发队列和Deques可供选择。

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

https://stackoverflow.com/questions/33831871

复制
相关文章

相似问题

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