gpt4 book ai didi

java - 同步链表 - peek

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:23:40 25 4
gpt4 key购买 nike

LinkedList 具有方便的peekpop、...方法。

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

List<Object> list = Collections.synchronizedList(new LinkedList<>());

但是,由于 List 接口(interface)不包含 peekpop 方法。这当然行不通。

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

我忽略了任何解决方案吗?


编辑:

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

更多背景信息:

  • 我正在使用 LinkedList,因为需要对项目进行排序。
  • 应以非阻塞方式添加项目。
  • 项目在后面添加;从前面移除。
  • 在删除第一项之前,首先需要对其进行查看和验证。如果验证失败,则该项目需要保留在列表中。
  • 只有当验证成功完成时,才会删除第一个项目。
  • 队列需要有一个最大大小(以避免内存问题)。

最佳答案

如果需要peek要工作,制作一个同步包装器可能还不够,所以你必须写 synchronized明确地。

与其说是编写包装器的问题,不如说是 peek 的语义问题。方法。不同于 pop方法,表示单个操作,peek方法常用于由peek组成的多组件 Action 中-然后根据什么做其他事情peek返回。

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

String s;
synchronized(list) {
s = list.peek();
}
// <<== Problem ==>>
if (s != null) {
synchronized(list) {
s = list.pop();
}
}

这会带来一个问题,因为有时您的列表可能会在 peek 之间发生变化。和 pop (上面代码中的这个地方被标记为“问题”)。

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

synchronized(list) {
String s = list.peek();
if (s != null) {
s = list.pop();
}
}

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

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

关于java - 同步链表 - peek,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33831871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com