public class CollectionDemo { public static void main(String[] args) { List<String> list = new ArrayList<String>(); for (int i = 1; i < 40; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0, 8)); System.out.println(list); }, "线程" + String.valueOf(i)).start(); } //list.forEach(System.out::println); } }
结果:发现不是打印出三个参数值,出现异常
Exception in thread "线程6" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at java.util.AbstractCollection.toString(Unknown Source) at java.lang.String.valueOf(Unknown Source) at java.io.PrintStream.println(Unknown Source) at com.shangguigu.collection.CollectionDemo.lambda$0(CollectionDemo.java:14) at java.lang.Thread.run(Unknown Source)
修改成集合安全
//ArrayList特性,初始化默认大小10,每次扩容一半,15,22 //先getArray(),size()+1,copyOf() public static void main(String[] args) { List<String> list = Collections.synchronizedList(new ArrayList<String>()); for (int i = 1; i < 40; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0, 8)); System.out.println(list); }, "线程" + String.valueOf(i)).start(); } //list.forEach(System.out::println); }
public static void main(String[] args) { List<String> list = new CopyOnWriteArrayList<>();//reentrantlock 底层,先复制改完,指针重指向新数组 for (int i = 1; i < 40; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0, 8)); System.out.println(list); }, "线程" + String.valueOf(i)).start(); } //list.forEach(System.out::println); }
hashSet和HashMap也一样
public static void main(String[] args) { //listdemo(); setdemo(); mapdemo(); } /** * HashMap初始值16,每次扩容一倍 */ private static void mapdemo() { Map<String,String> map = new ConcurrentHashMap<>();//Collections.synchronizedSet(new HashMap<>()); for (int i = 1; i < 40; i++) { new Thread(() -> { map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0, 8)); System.out.println(map); }, "线程" + String.valueOf(i)).start(); } } private static void setdemo() { Set<String> set = new CopyOnWriteArraySet<>();//Collections.synchronizedSet(new HashSet<>()); for (int i = 1; i < 40; i++) { new Thread(() -> { set.add(UUID.randomUUID().toString().substring(0, 8)); System.out.println(set); }, "线程" + String.valueOf(i)).start(); } }