gpt4 book ai didi

java - 在另一个线程读取 Java 列表引用时更改它

转载 作者:行者123 更新时间:2023-12-02 03:31:03 25 4
gpt4 key购买 nike

我找不到这个问题的明确答案,因此,如果其他地方对此问题有很好的回答,我深表歉意。

想象一下我有大致类似的东西:

Class SomeClass
{
List<String> strings = new LinkedList<>();


public void updateList(List<String> newStrings) {
strings = newStrings;
}

public List<String> getMatchingStrings(String pattern) {
List<String> matches = new LinkedList<>();
for (String s : strings) {
if (matchesPattern(s, pattern)) { //Assume this just works
matches.add(s);
}
}
return matches;
}

}

假设另一个线程调用updateList(...)当某个线程正在调用getMatchingStrings()时,会不会有“问题”?

预期的行为是当前执行的线程 getMatchingStrings()将在旧列表上运行,后续调用将在更新后的列表上运行。

感谢任何帮助!

最佳答案

您的代码中存在“不安全发布”(写入列表字段和读取列表字段之间没有“发生在顺序之前”)。使用阻塞的“同步”或非阻塞的“ volatile ”或“原子引用”:

// with 'synchronized'
class SomeClass0 {
List<String> strings = new LinkedList<>();

public synchronized void updateList(List<String> newStrings) {
this.strings = newStrings;
}

public synchronized List<String> getMatchingStrings(String pattern) {
List<String> matches = new LinkedList<>();
for (String s : strings) {
if (matchesPattern(s, pattern)) { //Assume this just works
matches.add(s);
}
}
return matches;
}
}

// with 'volatile'
class SomeClass1 {
volatile List<String> strings = new LinkedList<>();

public void updateList(List<String> newStrings) {
this.strings = newStrings;
}

public List<String> getMatchingStrings(String pattern) {
List<String> localCopy = this.strings;
List<String> matches = new LinkedList<>();
for (String s : localCopy) {
if (matchesPattern(s, pattern)) { //Assume this just works
matches.add(s);
}
}
return matches;
}
}

// with 'AtomicReference'
class SomeClass2 {
AtomicReference<List<String>> strings =
new AtomicReference<>(new LinkedList<>());

public void updateList(List<String> newStrings) {
this.strings.set(newStrings);
}

public List<String> getMatchingStrings(String pattern) {
List<String> localCopy = this.strings.get();
List<String> matches = new LinkedList<>();
for (String s : localCopy) {
if (matchesPattern(s, pattern)) { //Assume this just works
matches.add(s);
}
}
return matches;
}
}

关于java - 在另一个线程读取 Java 列表引用时更改它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38086999/

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