gpt4 book ai didi

java - 在 Java 中重新分配列表是线程安全的吗?

转载 作者:行者123 更新时间:2023-11-29 08:24:18 25 4
gpt4 key购买 nike

我正在玩两个在 ArrayList 上运行的线程。我知道您不能在迭代时修改列表,但是 Java 让我可以毫无问题地在循环中重新分配(替换)整个列表。这是线程安全的吗?

public class Main {

static List<String> list = Arrays.asList("hi", "there", "friend");

public static void main(String... args) throws InterruptedException {

boolean isReassigned = false;

for (String s: list) {
System.out.println(s);
if (!isReassigned) {
new Thread(() -> reassignList()).start();
isReassigned = true;
}
Thread.sleep(1000);
}
}

public static void reassignList() {
System.out.println("Reassigning list....");
list = Arrays.asList("goodbye", "old", "list");
}
}

我预计在“hi”之后会出现并发问题,但我得到了“hi there friend”。

我认为这是可行的,因为 Java 会在引用上按值复制,但我担心我的生产应用程序每 1 分钟重新分配一次数组,有一天可能会崩溃。谢谢大家!

最佳答案

您没有看到更新后的列表内容,因为增强的 for 循环在幕后使用了迭代器。因此,您正在使用迭代器(到旧列表)来迭代数据(即使在分配完成之后)。这意味着这两个列表都在范围内(而不是垃圾收集)。一旦 isReassigned 为真,如果您获得 list 的迭代器,您就可以看到新内容。

我稍微修改了你的代码(添加了一个 else block )以理解这一点

for (String s: list) {
System.out.println(s);
if (!isReassigned) {
new Thread(() -> reassignList()).start();
isReassigned = true;
} else {
System.out.println("Latest data " + list);
}
Thread.sleep(1000);
}

这产生

hi
Reassigning list....
there
Latest data [goodbye, old, list]
friend
Latest data [goodbye, old, list]

其他几点:

  1. 您不应该从主线程设置 isReassigned。必须在分配列表后进行设置。

  2. 正如@Kartik 在评论中指出的那样,可能存在可见性问题,其他线程可能看不到所做的更改。标记列表和 isReassigned volatile 将解决这个问题。

关于java - 在 Java 中重新分配列表是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54642798/

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