我正在尝试理解ArrayList和Vector的行为差异。下面的代码片段是否以任何方式说明了同步的差异? ArrayList(f1)的输出是不可预测的,而Vector(f2)的输出是可预测的。我认为f2具有可预测的输出可能只是运气,因为稍微修改f2以使线程进入睡眠状态甚至一个ms(f3)会导致空向量!是什么造成的?
public class D implements Runnable {
ArrayList<Integer> al;
Vector<Integer> vl;
public D(ArrayList al_, Vector vl_) {
al = al_;
vl = vl_;
}
public void run() {
if (al.size() < 20)
f1();
else
f2();
} // 1
public void f1() {
if (al.size() == 0)
al.add(0);
else
al.add(al.get(al.size() - 1) + 1);
}
public void f2() {
if (vl.size() == 0)
vl.add(0);
else
vl.add(vl.get(vl.size() - 1) + 1);
}
public void f3() {
if (vl.size() == 0) {
try {
Thread.sleep(1);
vl.add(0);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
} else {
vl.add(vl.get(vl.size() - 1) + 1);
}
}
public static void main(String... args) {
Vector<Integer> vl = new Vector<Integer>(20);
ArrayList<Integer> al = new ArrayList<Integer>(20);
for (int i = 1; i < 40; i++) {
new Thread(new D(al, vl), Integer.toString(i)).start();
}
}
}
答案 0 :(得分:4)
回答这个问题:是向量是同步的,这意味着对数据结构本身的并发操作不会导致意外行为(例如NullPointerExceptions等)。因此size()
之类的调用在并发情况下使用Vector
是完全安全的,但不是ArrayList
调用(请注意,如果只有读取访问,ArrayLists也是安全的,我们会尽快遇到问题因为至少有一个线程写入数据结构,例如添加/删除)
问题是,这种低级同步基本上完全没用,你的代码已经证明了这一点。
if (al.size() == 0)
al.add(0);
else
al.add(al.get(al.size() - 1) + 1);
这里你想要的是根据当前大小为数据结构添加一个数字(即如果N个线程执行此操作,最后我们希望列表包含数字[0..N)
)。可悲的是,这不起作用:
假设2个线程在空列表/向量上并发执行此代码示例。以下时间表很可能:
T1: size() # go to true branch of if
T2: size() # alas we again take the true branch.
T1: add(0)
T2: add(0) # ouch
两者都执行size()
并返回值0.然后它们进入真正的分支,并且都将0
添加到数据结构中。那是不是你想要的。
因此,您无论如何都必须在业务逻辑中进行同步,以确保size()
和add()
以原子方式执行。因此,几乎在任何情况下,向量的同步都是无用的(与现代JVM上的一些声明相反,无竞争锁的性能损失完全可以忽略不计,但Collections API更好,所以为什么不使用它)
答案 1 :(得分:0)
In The Beginning(Java 1.0)中有“同步向量”。
这可能会导致巨大的性能损失。
因此在Java 1.2之后添加了“ArrayList”和朋友。
您的代码说明了首先使矢量同步的基本原理。但是大部分时间它都是不必要的,而其他时间大部分时间都是以其他方式做得更好。
... IMHO
PS: 一个有趣的链接:
http://www.coderanch.com/t/523384/java/java/ArrayList-Vector-size-incrementation
答案 2 :(得分:0)
向量是线程安全的。 ArrayLists不是。这就是ArrayList比矢量更快的原因。 以下链接有很好的信息。
http://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html
答案 3 :(得分:0)
我正在尝试理解ArrayList的行为差异 和一个矢量
Vector
为synchronized
,而ArrayList
则不是。 ArrayList
不是线程安全的。
以下代码段是否以任何方式说明了其中的区别 同步?
没有区别,因为只有Vector
是sunchronized