2012-11-15 54 views
0
List<Integer> contacts = new Vector<Integer>(); 

Collections.sort(contacts); 

好的我知道一个向量是线程安全的,但是如果我这样做有什么问题吗?线程安全java - 收集/列表

+1

什么样的问题?线程安全意味着很多事情。 – jtahlborn

+1

我想你的意思是:列表 contacts = new Vector (); Collections.sort(contacts); 至于线程安全性,除非您将联系人存储在本地变量之外,否则不用担心,因为只有一个线程可以访问它。 –

+0

为什么你认为这个代码会有线程安全问题? –

回答

2

载体是线程安全的

其方法是每一个线程安全的。但是Collections.sort将迭代不是原子操作的向量。特别是,Vector's javadoc规定:

如果向量在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身的remove或add方法,迭代器都将抛出ConcurrentModificationException。

因此,如果您的向量在排序时被另一个线程修改,您将得到一个异常。

多个线程可以访问您的结构的替代方法包括:制作防御副本或使用并发结构(如CopyOnWriteArrayList)。

+0

有没有一种方法可以使Collection线程安全或者是一种对它进行排序的方法? – Andrew

+0

简单的方法是复制副本并对其进行排序。 – assylias

2

您可以使用此使此代码线程安全的:

List<Integer> contacts = new Vector<Integer>(); 

synchronized(contacts) { 
    Collections.sort(contacts); 
} 
+0

+1当然是! – assylias

0

使用Collections.sort(任何)是做一个很幼稚的事情。

如果你看那种方法签名,你会看到他们都在列表上,这是不保证线程安全的操作: sort(List<T> list) sort(List<T> list, Comparator<? super T> c)

即使你使用旧(旧来讲Java历史)对象,像Vector一样,你的代码变得容易冒险,因为下一个开发者(或者甚至你自己)可能会决定使用ArrayList。

排序具有破坏性的行为,即它正在修改底层集合,并未能同步,可能导致你喜欢的东西:

java.util.ConcurrentModificationException: null at java.util.ArrayList.sort (...)

同步代码可以是一个有点棘手,以及后来的java实现提供了许多功能来绕过“手动同步”你的代码。

所以我会做的是:

Collections.sort (Collections.synchronizedList (myList))