【发布时间】:2021-11-14 03:36:11
【问题描述】:
我试图了解final 字段在多线程环境中的作用。
我阅读了这些相关的帖子:
final fields and thread-safety
Java concurrency: is final field (initialized in constructor) thread-safe?
Java: Final field freeze on object reachable from final fields
并尝试模拟final 字段将阻止线程使用未完全构造的对象的情况。
public class Main {
public static void main(String[] args) {
new _Thread().start();
new Dummy();
}
static class _Thread extends Thread {
static Dummy dummy;
@Override
public void run() {
System.out.println(dummy.getIntegers().size() == 10_000);
}
}
static class Dummy {
private final List<Integer> integers = new ArrayList<>();
public Dummy() {
_Thread.dummy = this;
for (int a = 0; a < 10_000; a++) {
integers.add(a);
}
}
public List<Integer> getIntegers() {
return integers;
}
}
}
据我了解,_Thread 将在getIntegers() 上停止执行并等待循环完成填充收集。但是integers字段是否有final修饰符,run()的结果是不可预测的。我也知道有NPE的可能。
【问题讨论】:
-
你到底在问什么?据我所知,这个“问题”实际上并不包含任何问题。只是一个意图声明,以及一些关于您认为该代码应该如何表现的断言。您实际上希望我们在这里回答什么?
-
IMO,您混淆了“完全构造”的含义。
ArrayList实例在“完全构造”时为空。然后,Dummy构造函数改变列表,在列表被“构造”之后。您对final的使用可防止其他线程看到处于未构造状态的list,但您允许其他线程在Dummy完全构造之前看到Dummy实例。你允许它看到Dummy,而它的构造函数仍在改变列表。
标签: java multithreading final