java - 线程安全 - 传递给线程的最终局部方法变量?

标签 java multithreading concurrency thread-safety final

如果此方法的变量“commonSet”改为类级字段,以下代码是否会导致同样的问题。如果它是一个类级别的字段,我将不得不在一个同步块(synchronized block)中将添加到集合操作包装起来,因为 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) 的堆栈内存和运行方法的堆栈内存上——这是正确的吗?

有很多与此相关的问题:

但是,我看不到他们强调这种共享/传递可变变量的线程安全部分。

最佳答案

不,这绝对不是线程安全的。仅仅因为您将它放在最终变量中,这意味着两个线程将看到相同的引用,这很好 - 但它不会使对象成为任何对象更线程安全。

要么需要同步访问,要么使用ConcurrentSkipListSet .

关于java - 线程安全 - 传递给线程的最终局部方法变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11824264/

相关文章:

c# - Application.DoEvents vs await Task.Delay 循环

java - 数据插入 mongodb 错误中的问题

java - JSF中直接修改URL限制用户访问页面

java - 通过提交选项更新数据库

java - 不可刷新的Jsp页面

python - 减少 wxPython GUI 加载时间的方法

c++ - 如何获取 std::thread() 的 Linux 线程 ID

java - 当一个线程获取锁时,其他线程是否可以调用其他方法?

c++ - gcc-c++ 是否没有为当前的 x86-64 处理器优化原子操作

乱序执行的iOS代码