>我试图理解ArrayList和Vector的行为差异。以下代码片段是否以任何方式说明了同步的差异?ArrayList (f1( 的输出是不可预测的,而 Vector (f2( 的输出是可预测的。我认为 f2 具有可预测的输出可能只是运气,因为稍微修改 f2 以使线程休眠甚至一毫秒 (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();
}
}
}
要回答这个问题:是的,向量是同步的,这意味着对数据结构本身的并发操作不会导致意外行为(例如 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 上的一些声明相反,无争议锁的性能影响完全可以忽略不计,但集合 API 要好得多,所以为什么不使用它(
在The Beginning(Java 1.0(中,有"同步向量"。
这会带来潜在的巨大性能打击。
因此,在Java 1.2之后添加了"ArrayList"和friends。
您的代码首先说明了使矢量同步的基本原理。 但大多数时候根本不需要这样做,其余大部分时间最好以其他方式完成。
恕我直言...
附注:一个有趣的链接:
http://www.coderanch.com/t/523384/java/java/ArrayList-Vector-size-incrementation
向量是线程安全的。ArrayLists不是。这就是为什么ArrayList比向量更快。下面的链接有关于这个的很好的信息。
http://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html
我试图了解数组列表的行为差异 和矢量
Vector
是synchronized
,而ArrayList
不是。 ArrayList
不是线程安全的。
以下代码片段是否以任何方式说明了 同步?
没有区别,因为只有Vector
是sunchronized