Q1:ArrayList你项目中有使用吗? A1:第一问等于没问。肯定用,而且频率还挺高。
Q2:第二问线程不安全。 A2:为啥呢。看代码噶
public class NotSafeDemo{
public static void main(String[] args) {
List<String> list = new ArrayList<>();
for (int i = 1; i <= 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
}
运行后啥结果? console log ==>>java.util.ConcurrentModificationException 都报错啦
"C:\Program Files\Java\jdk1.8.0_221\bin\java.exe" -Dvisualvm.id=23079082219200 "-javaagent:D:\IntelliJ IDEA 2019.2\lib\idea_rt.jar=55287:D:\IntelliJ IDEA 2019.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_221\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\rt.jar;E:\Github\Interview\target\classes" com.aicode.Interview.study.thread.ContainerNotSafeDemo
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402]Exception in thread "16"
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d, 32835416, 30a020f2, 3d9b07e4]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d, 32835416, 30a020f2, 3d9b07e4, 028db197]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d, 32835416, 30a020f2, 3d9b07e4, 028db197, 1e03c5a0, cf367d22]
Exception in thread "28" [null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d, 32835416, 30a020f2, 3d9b07e4, 028db197, 1e03c5a0]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d, 32835416, 30a020f2, 3d9b07e4, 028db197, 1e03c5a0, cf367d22, cf30b7f3, 64f2312a, 3219bcd3, 91d0033c]
java.util.ConcurrentModificationException
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d, 32835416, 30a020f2]
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d, 32835416]
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.io.PrintStream.println(PrintStream.java:821)
at com.aicode.Interview.study.thread.ContainerNotSafeDemo.lambda$main$0(ContainerNotSafeDemo.java:29)
at java.lang.Thread.run(Thread.java:748)
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634]
java.util.ConcurrentModificationException
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5]
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71]
at java.util.ArrayList$Itr.next(ArrayList.java:859)[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5]
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.io.PrintStream.println(PrintStream.java:821)
at com.aicode.Interview.study.thread.ContainerNotSafeDemo.lambda$main$0(ContainerNotSafeDemo.java:29)
at java.lang.Thread.run(Thread.java:748)
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d, 32835416, 30a020f2, 3d9b07e4, 028db197, 1e03c5a0, cf367d22, cf30b7f3, 64f2312a, 3219bcd3]
[null, 74cddd12, 3c52b8ad, 25153294, 46a688b6, e4007402, 7a7bb89a, 5bf37fed, a3c1f38d, 5fb7bf59, 67adf92b, 4703d43e, d57a43f5, 2faa4d71, c6ba36f5, 7a3f33ed, 82af6c70, a799bba9, ae2d6634, 4f26fc9d, 32835416, 30a020f2, 3d9b07e4, 028db197, 1e03c5a0, cf367d22, cf30b7f3]
那咱们怎么保证安全呢?
第一种 首先想到的肯定是给list加锁。 对的,那你首先想到jdk自带的Vertor<>();
这个类里的方法都是由synchronized修饰的。肯定安全的,但是你可以想到,方法上加sync虽然保证了结果没问题,但是性能上肯定被砍了一刀。我们要性能。那你用这个肯定满足不了要求的。
第二种 so.我们还有方法。Collecetions应该都是知道是Collection的工具类,为Collection提供了很多常用方法。
Collections.synchronizedList(new ArrayList<>());
我们可以看到,这个类也是关键字sync修饰的,里面还有synchronizedMap啥的。
说明这些Set,Map,List都是不安全的

java.util.Collections.SynchronizedList它能把所有 List 接口的实现类转换成线程安全的List,比 Vector 有更好的扩展性和兼容性,很可惜,它所有方法都是带同步对象锁的,和 Vector 一样,它不是性能最优的
第三种 如果还不能满足,那你可以使用更加好方式,JUC包的方法 ,CopyOnWriteArrayList 还是看源码:
看到了 ReentrantLock(可重入锁)+ volatile 来保证并发安全

即复制再写入,就是在添加元素的时候,先把原 List 列表复制一份,再添加新的元素。 添加元素时,先加锁,再进行复制替换操作,最后再释放锁。

可以看到,获取元素并没有加锁。 这样做的好处是,在高并发情况下,读取元素时就不用加锁,写数据时才加锁,大大提升了读取性能。

那么如果有问到如何保证多线程下的list的安全。
1.使用Vector 2.Collections.synchronizedList(new ArrayList<>()); 3.new CopyOnWriteArrayList<>();