36、SynchronizedMap 和 ConcurrentHashMap 有什么区 别?
SynchronizedMap 一次锁住整张表来保证线程安全,所以每次只能有一个线程来 访为 map。 ConcurrentHashMap 使用分段锁来保证在多线程下的性能。
ConcurrentHashMap 中则是一次锁住一个桶。ConcurrentHashMap 默认将 hash 表分为 16 个桶,诸如 get,put,remove 等常用操作只锁当前需要用到的桶。 这样,原来只能一个线程进入,现在却能同时有 16 个写线程执行,并发性能的提 升是显而易见的。 另外 ConcurrentHashMap 使用了一种不同的迭代方式。在这种迭代方式中,当 iterator 被创建后集合再发生改变就不再是抛出 ConcurrentModificationException,取而代之的是在改变时 new 新的数据从而 不影响原有的数据 ,iterator 完成后再将头指针替换为新的数据 ,这样 iterator 线程可以使用原来老的数据,而写线程也可以并发的完成改变。
37、CopyOnWriteArrayList 可以用于什么应用场景?
CopyOnWriteArrayList(免锁容器)的好处之一是当多个迭代器同时遍历和修改这 个列表时,不会抛出 ConcurrentModificationException。在 CopyOnWriteArrayList 中,写入将导致创建整个底层数组的副本,而源数组将保 留在原地,使得复制的数组在被修改时,读取操作可以安全地执行。
1、由于写操作的时候,需要拷贝数组,会消耗内存,如果原数组的内容比较多的 情况下,可能导致 young gc 或者 full gc;
2、不能用于实时读的场景,像拷贝数组、新增元素都需要时间,所以调用一个 set 操作后,读取到数据可能还是旧的,虽然 CopyOnWriteArrayList 能做到最终一致 性,但是还是没法满足实时性要求; CopyOnWriteArrayList 透露的思想 :
1、读写分离,读和写分开 2、最终一致性 3、使用另外开辟空间的思路,来解决并发冲突
38、什么叫线程安全?servlet 是线程安全吗?
线程安全是编程中的术语,指某个函数、函数库在多线程环境中被调用时,能够 正确地处理多个线程之间的共享变量,使程序功能正确完成。 Servlet 不是线程安全的,servlet 是单实例多线程的,当多个线程同时访问同一个 方法,是不能保证共享变量的线程安全性的。 Struts2 的 action 是多实例多线程的,是线程安全的,每个请求过来都会 new 一 个新的 action 分配给这个请求,请求完成后销毁。 SpringMVC 的 Controller 是线程安全的吗?不是的,和 Servlet 类似的处理流程。 Struts2 好处是不用考虑线程安全问题;Servlet 和 SpringMVC 需要考虑线程安 全问题,但是性能可以提升不用处理太多的 gc,可以使用 ThreadLocal 来处理多 线程的问题。
39、volatile 有什么用?能否用一句话说明下 volatile 的应用 场景?
volatile 保证内存可见性和禁止指令重排。 volatile 用于多线程环境下的单次操作(单次读或者单次写)。
40、为什么代码会重排序?
在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是 不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件: 在单线程环境下不能改变程序运行的结果; 存在数据依赖关系的不允许重排序 需要注意的是:重排序不会影响单线程环境的执行结果,但是会破坏多线程的执 行语义。