Java 存储在线程安全集合中的对象是否线程安全?

Java 存储在线程安全集合中的对象是否线程安全?,java,multithreading,concurrency,Java,Multithreading,Concurrency,存储在线程安全集合(如CopyOnWriteArrayList)中的对象是否线程安全?假设存储的对象是可变的而不是线程安全的,那么CopyOnWriteArrayList中的集合是线程安全的这一事实为存储在其中的引用的线程安全提供了任何保证?否,对象不是线程安全的;如果两个线程更改了从CopyOnWriteArrayList检索到的可变对象,那么它们将导致数据竞争 如果集合是线程安全的,则这意味着两个线程可以在不损坏集合的情况下从集合中添加/删除对象。例如,ArrayList不是线程安全的,因此

存储在线程安全集合(如CopyOnWriteArrayList)中的对象是否线程安全?假设存储的对象是可变的而不是线程安全的,那么CopyOnWriteArrayList中的集合是线程安全的这一事实为存储在其中的引用的线程安全提供了任何保证?

否,对象不是线程安全的;如果两个线程更改了从CopyOnWriteArrayList检索到的可变对象,那么它们将导致数据竞争


如果集合是线程安全的,则这意味着两个线程可以在不损坏集合的情况下从集合中添加/删除对象。例如,ArrayList不是线程安全的,因此如果两个线程都尝试向集合添加对象,则一个或两个对象可能会丢失,但是,集合中的对象仍需要同步,以使其具有线程安全性。

有一些保证,通常线程安全存储在内存效果方面类似于易失性变量

volatile Foo var;              final Vector<Foo> vars = new Vector<>()

// thread 1                    // thread 1
foo.bar = bar;  [1]            foo.bar = bar;         [1]
var = foo;                     vars.set(0, foo);

// thread 2                    // thread 2
bar = foo.bar;  [2]            bar = vars.get(0).bar; [2]

//read[2] sees write[1]        // read[2] sees write[1]

基本上,插入前的写入应该在检索后对读取可见。

提供的唯一线程安全保证是对象将“安全发布”。也就是说,它们将立即对所有线程可见,这包括对对象及其内部状态的引用

示例:如果线程A写X,线程B读,则B保证将X视为它的左边。换句话说,读写操作与它们发生的顺序是一致的


还有其他方法可以完成同样的事情,比如使用final、volatile、AtomicReference或锁——这就是线程安全集合正在做的事情,或者使用静态初始值设定项。有关详细信息,请参阅《实践中的Java并发性》一书。

对不起,你在问什么?你说的是集合支持的数组中的引用变量,还是集合中的实际对象?对不起,我的问题不清楚。我指的是集合中的对象。是的,但是太多的同步可能会导致程序运行速度慢得多,或者在某些情况下出现死锁。是的,这就是为什么Java放弃了总是使用Vector或Stringbuffer之类的类来同步所有内容的方法,转而使用让程序员决定使用ArrayList或Stringbuffer之类的类来同步方法的原因StringWriter@gparyani-太多的同步不会导致死锁。死锁是由不正确的同步模式引起的。区别在于模式而不是数量。@StephenC我只是引用了Head First Java的话。我想这有点模棱两可。