1

我试图了解 Vector 和 ArrayList 类在线程安全方面的区别。Vector 应该是内部同步的。它是由每个元素同步的,还是作为一个整体同步的?(我可以想象多个线程可以同时访问向量,但多个线程不能同时访问同一个元素的情况)。如果您查看下面的代码,getAo()则不等于,getV()因为据我所知synchronized,在方法签名中使用的关键字会在包含的类对象( 的实例)上同步。VectorVsArrayList但是,getAoSync()相当于getV()?等同于,我的意思是ao只要对实例变量的所有访问都通过getter方法,就同步而言,实例变量开始表现得像一个Vector对象?

public class VectorVsArrayList {

        private ArrayList<?> ao = null;
        private Vector<?> v = null;



        public ArrayList<?> getAoSync(){
            synchronized(ao){
                return ao;
            }
        }


        public synchronized ArrayList<?> getAo() {
            return ao;
        }


        public Vector<?> getV() {
            return v;
        }

    }
4

3 回答 3

1

简短的回答:不,它不等同。

当您使用synchronizedaround thatreturn ao;时,ArrayList仅在返回指令期间同步。这意味着 2 个线程不能同时获取对象,但是一旦它们得到它,它们就可以同时修改它。

如果 2 个线程执行此代码,add()则不是线程安全的:

ArrayList<?> list = getAo(); // cannot be executed concurrently
list.add(something); // CAN be executed concurrently

旁注:不要使用向量,看看这篇文章就知道为什么了。

于 2014-03-20T17:02:40.220 回答
1

它们不是等价的。您正在寻找的是Collections.synchronizedList可以“环绕”任何列表的内容,包括ArrayList.

于 2014-03-20T17:05:02.533 回答
1

要执行 Vector 的等效操作,您应该保护对集合中任何元素的任何访问,getAo 方法只是简单地同步对数组列表的访问。

如果两个线程调用 getAo 并且每个线程在此数组列表上调用“add”方法之后,那么您可能会遇到多线程问题(因为“add”不同步)。

我建议你检查像 CopyOnWriteArrayList 这样的原子类:http: //docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

于 2014-03-20T17:11:57.707 回答