bvd*_*vdb 5 java linked-list thread-safety peek
ALinkedList有方便的peek, pop, ... 方法。
不幸的是,我需要一个线程安全的LinkedList. 所以,我的第一个想法是将其包装如下:
List<Object> list = Collections.synchronizedList(new LinkedList<>());
Run Code Online (Sandbox Code Playgroud)
但是,由于该List接口不包含peek或pop方法。这当然行不通。
或者,我可以synchronized(list)在整个代码中使用块。这是要走的路吗?
我忽略了任何解决方案吗?
编辑:
人们使用LinkedList. 我看到有些人正在推荐其他系列。因此,这里遵循简短的要求,这导致我决定使用LinkedList.
更多背景信息:
peek编辑和验证。如果验证失败,则该项目需要保留在列表中。如果您需要peek工作,制作同步包装器可能还不够,因此您必须synchronized显式编写。
与其说是编写包装器的问题,不如说是方法语义的问题peek。pop与表示单个操作的方法不同,peek方法通常用于由 -ing 组成的多组件操作peek,然后根据peek返回的内容执行其他操作。
如果您在包装器中进行同步,则结果将与手动编写此代码相同:
String s;
synchronized(list) {
s = list.peek();
}
// <<== Problem ==>>
if (s != null) {
synchronized(list) {
s = list.pop();
}
}
Run Code Online (Sandbox Code Playgroud)
这提出了一个问题,因为有时您的列表可能会在 和 之间发生变化peek(pop上面代码中的这个地方被标记为“问题”)。
进行检查和修改的正确方法是在单个块中进行synchronized,即
synchronized(list) {
String s = list.peek();
if (s != null) {
s = list.pop();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这无法在简单的包装器中完成,因为两个列表操作是在单个synchronized块中执行的。
您可以synchronized通过构建自己的数据结构来避免在多个位置进行写入,该数据结构封装LinkedList<T>, 并提供在同步块中执行所有测试和修改操作的操作。然而,这不是一个简单的问题,因此您最好更改算法,使其可以与预定义的并发容器之一一起使用。
| 归档时间: |
|
| 查看次数: |
12515 次 |
| 最近记录: |