hap*_*s10 8 java concurrency multithreading final thread-safety
如果此方法的变量'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();
}
Run Code Online (Sandbox Code Playgroud)
'commonSet'的引用是使用final锁定的.但是在其上运行的多个线程仍然可以破坏集合中的值(它可能包含重复项?).其次,混淆是因为'commonSet'是一个方法级变量 - 它的相同引用将在调用方法的堆栈内存(threadCreatorFunction)和运行方法的堆栈内存 - 这是正确的吗?
有很多与此相关的问题:
但是,我不能看到他们强调线程安全部分这种共享/传递可变性.
不,这绝对不是线程安全的.只是因为你已经在最终变量中得到它,这意味着两个线程都会看到相同的引用,这很好 - 但它不会使对象更加线程安全.
您需要同步访问或使用ConcurrentSkipListSet
.
一个有趣的例子.
引用commonSet
是线程安全且不可变的.它位于第一个线程的堆栈和匿名Runnable
类的字段中.(你可以在调试器中看到这个)
集合commonSet
引用是可变的而不是线程安全的.您需要使用synchronized或Lock来使其线程安全.(或者使用线程安全集合代替)
归档时间: |
|
查看次数: |
2624 次 |
最近记录: |