如果此方法的变量“commonSet”改为类级别字段,则以下代码是否会导致相同的问题。如果它是一个类级别的字段,我将不得不在同步块中包装添加到设置操作,因为 HashSet 不是线程安全的。我是否应该在下面的代码中做同样的事情,因为多个线程正在添加到集合中,甚至当前线程可能会继续改变集合。
public void threadCreatorFunction(final String[] args) {
final Set<String> commonSet = new HashSet<String>();
final Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
commonSet.add(newValue());
}
}
};
new Thread(runnable, "T_A").start();
new Thread(runnable, "T_B").start();
}
对“commonSet”的引用通过使用 final 被“锁定”。但是在它上面运行的多个线程仍然可以破坏集合中的值(它可能包含重复项?)。其次,混淆是因为“commonSet”是一个方法级别的变量——它的相同引用将在调用方法(threadCreatorFunction)的堆栈内存和运行方法的堆栈内存上——这是正确的吗?
有很多与此相关的问题:
但是,我看不到他们强调这种共享/传递可变变量的线程安全部分。