Java 向量与集合。同步列表(ArrayList)

Java 向量与集合。同步列表(ArrayList),java,collections,vector,arraylist,Java,Collections,Vector,Arraylist,向量是同步的,ArrayList是不同步的,但是我们可以通过集合来同步ArrayList。synchronizedList(aList),所以哪一个会执行得更好更快?同步的集合既浪费时间又危险。一个简单的例子,为什么他们是坏的是要考虑两个线程同时运行一个循环在同一个集合:< /P> int i = 0; while (i < list.size()) { if (testSomeCondition(list.get())) { list.remove(i); else

向量是同步的,ArrayList是不同步的,但是我们可以通过
集合来同步ArrayList。synchronizedList(aList)
,所以哪一个会执行得更好更快?

同步的集合既浪费时间又危险。一个简单的例子,为什么他们是坏的是要考虑两个线程同时运行一个循环在同一个集合:< /P>
int i = 0;
while (i < list.size())
{
  if (testSomeCondition(list.get())) {
    list.remove(i);
  else
    i++;
}
inti=0;
而(i
我们的列表可能会被同步(例如一个向量),而这段代码仍然会非常糟糕。为什么?因为对size()、get()、remove()的单独调用,但一个线程可能仍在从列表中删除项目,而另一个线程正在对其进行迭代。换句话说,我们有一个竞争条件,使用同步集合对我们没有任何好处

为了修复竞争,我们必须同步集合上的整个操作,或者使用Java5并发锁来完成同样的操作

synchronized (list) {
  int i = 0;
  while (i < list.size())
  {
    if (testSomeCondition(list.get())) {
      list.remove(i);
    else
      i++;
  }
}
已同步(列表){
int i=0;
而(i
这段代码现在是线程安全的,因为一次只有一个线程可以执行循环。现在没有理由使用同步集合。我们可以使用ArrayList而不是Vector,这样就可以避免所有同步调用的性能损失


因此,不要使用同步集合。如果您发现自己有多个线程访问同一个列表,那么您需要保护列表上的操作,而不是单个调用。

如果这是C#,请用“C#”或“.NET”标记您的问题。为什么不编写一个测试并找出答案?您能解释一下使用模式吗?1)多写/多读2)少写,多读,3)多写,少读4)少写/少不需要优化另请参见“同步收集是浪费时间。”--太笼统了。同步的集合有一个目的。你只是给出了一个如何错误使用它们的示例。Strawman参数。它们完全是在浪费时间。Synchronized关键字施加调用惩罚,即使集合仅由单个线程使用。而且大多数集合将仅由单个线程使用即使它们是共享的,那么同步单个调用仍然会考虑竞争条件,因此它们不适合使用。开发人员只是浪费时间在他们所谓的线程安全集合中查找bug。简单地说,这些集合是有毒的,除非无法避免,否则不应使用(例如遗留案例、J2ME等)。在java 1.3及更早版本中,同步速度较慢。在现代java中,同步速度更好。此外,还有一些似是而非的参数。没有人在已知为单线程的情况下使用同步。您的第一个示例就是糟糕的编程,没有任何集合可以弥补这一点。您只需想想什么是原子r,什么不是原子reGardles是您使用的集合的一部分在ArrayList中,您将看到为什么需要同步此方法以保持列表的完整性。世界上充斥着糟糕的编程。该示例旨在简单地说明,同步集合是一种很有吸引力的讨厌的东西,实际上可能会导致错误-它们看起来很安全,但实际上并不安全。它更有效,更安全显然,保护整个操作和在内部使用非同步集合更安全。Sun清楚地认识到其原始类的问题,这就是为什么他们将它们推到一边,支持非同步版本。此响应并没有回答问题。相反,它说不要担心线程安全集合。