1 怎么确保一个集合不能被修改?
可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合,这样改变集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。
示例代码如下:
List<String> list = new ArrayList<>();
list. add("x");
Collection<String> clist = Collections. unmodifiableCollection(list);
clist. add("y"); // 运行时此行报错
System. out. println(list. size());
2 为什么 ArrayList 的 elementData 加上 transient 修饰?
加上transient 修饰可以让elementData不被序列化, 这么做的好处是在进行序列化的时候遍历elementData,只序列化已存入的元素,这样既加快了序列化的速度,又减小了序列化之后的文件大小。
3 线程安全的List的集合, 它们之间的区别
1.vector 和 arrayList 源码一样, 只是增加了synchronized 同步
2.synchronizedList 通过Collections.synchronizedList(List list) 内部也是通过synchronized 同步
3.CopyOnWriteArrayList 在add 和remove的时候会复制一个新数组去替换当前的数组,
只有写的时候才会同步, 适合读多写少的场景
4 多线程中 synchronized 锁升级的原理是什么?
synchronized 锁升级原理:在锁对象的对象头里面有一个 threadid 字段,在第一次访问的时候 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id,再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了 synchronized 锁的升级。
锁的升级的目的:锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗。
5 多线程锁的升级原理是什么? 在Java中,锁共有4种状态,级别从低到高依次为:无状态锁,偏向锁,轻量级锁和重量级锁状态,这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级。