gpt4 book ai didi

java - ArrayList 与 Vector - 这是否说明了同步方面的差异?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:22:24 25 4
gpt4 key购买 nike

我试图了解 ArrayList 和 Vector 的行为差异。以下片段是否以任何方式说明了同步的差异? ArrayList (f1) 的输出是不可预测的,而 Vector (f2) 的输出是可预测的。我认为 f2 具有可预测的输出可能只是运气,因为稍微修改 f2 以使线程 hibernate 甚至 ms (f3) 会导致空 vector !是什么原因造成的?

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();
}
}
}

最佳答案

回答这个问题:是的, vector 是同步的,这意味着对数据结构本身的并发操作不会导致意外行为(例如 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 个线程在空列表/vector 上同时执行此代码示例。以下时间表很有可能:

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() 以原子方式执行。因此,vector 的同步几乎在任何情况下都毫无用处(与现代 JVM 的一些说法相反,无竞争锁对性能的影响完全可以忽略不计,但 Collections API 更好,所以为什么不使用它)

关于java - ArrayList 与 Vector - 这是否说明了同步方面的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10557696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com