我对这段代码有两个问题:
import java.util.*;
public class TestClass {
private static List<String> list;
public static void main(String[] argv) {
list = generateStringList(new Random(), "qwertyuioasdfghjklzxcvbnmPOIUYTREWQLKJHGFDSAMNBVCXZ1232456789", 50, 1000);
// Collections.sort(list, new Comparator<String>() {
// public int compare(String f1, String f2) {
// return -f1.compareTo(f2);
// }
// });
for (int i = 0; i < 500; i++) {
new MyThread(i).start();
}
}
private static class MyThread extends Thread {
int id;
MyThread(int id) { this.id = id; }
public void run() {
Collections.sort(list, new Comparator<String>() {
public int compare(String f1, String f2) {
return -f1.compareTo(f2);
}
});
for (Iterator it = list.iterator(); it.hasNext();) {
String s = (String) it.next();
try {
Thread.sleep(10 + (int)(Math.random()*100));
}catch (Exception e) { e.printStackTrace(); }
System.out.println(id+" -> "+s);
}
}
}
public static List<String> generateStringList(Random rng, String characters, int length, int size)
{
List<String> list = new ArrayList<String>();
for (int j = 0; j < size; j++) {
char[] text = new char[length];
for (int i = 0; i < length; i++)
{
text[i] = characters.charAt(rng.nextInt(characters.length()));
}
list.add(new String(text));
}
return list;
}
}
在 java 1.8.0_45 上运行此代码我得到java.util.ConcurrentModificationException
.
1)如果我在 thread.start 之前取消排序,为什么我也会得到异常?
2)为什么我只在java 1.8.0_45上遇到异常?在 1.6.0_45、1.7.0_79、1.8.0_5 上工作正常。
@nbokmans已经确定了一般原因为什么你会得到这个例外。然而,这似乎确实与版本有关。我将解释为什么你在 java 8.0_45 中得到它,但在 1.6.0_45、1.7.0_79、1.8.0_5 中却没有。
这是因为 Collections.sort() 在 java 8.0_20 中发生了更改。有一篇文章对此有深入的了解here。在新版本中,按照文章的说法,排序是这样的:
public void sort(Comparator<? super E> c) {
final int expectedModCount = modCount;
Arrays.sort((E[]) elementData, 0, size, c);
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
就像文章解释的那样:
与旧的 Collections.sort 相反,此实现修改了
列表完成后,集合的 modCount(上面第 7 行)
已排序,即使结构本身没有真正改变(仍然是
相同数量的元素)。
因此,即使集合已经排序,它也会进行内部更改,而在更改之前它不会这样做。这就是为什么你现在得到例外。
实际的修复是不要同时使用多个线程对集合进行排序。你不应该这样做。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)