1.Java中有哪些容器?

Java中的集合主要有两个接口,Map 和 Collection。

Collection接口的子接口有List, Set, Queue。

常见的实现类:

List: LinkedList, ArrayList

Set:HashSet, TreeSet(继承于SortedSet接口)

Queue: ArrayDeque(继承于Deque)

Map: HashMap, HashTable, TreeMap(根据键的大小排序), LinkedHashMap(根据插入顺序排序)

2.容器的线程安全问题

java.util包下的容器大部分是非线程安全的。

线程安全的实现类有HashTable, Vector,这两个类的内部方法是加了synchronized关键字,所以线程安全,但是性能不好,不建议使用。

Collections使用装饰器模式,提供了线程安全的包装类。

JAVA5之后提供juc包, 提供了线程安全的高性能实现类。主要包括三类:Blocking类,Concurrent类,CopyOnWrite类。

Concurrent:

内部很多操作使用 cas 优化,缩小锁粒度等操作

比如jdk1.7的ConcurrentHashMap,分段加锁。 jdk1.8 CAS + synchronized + Node + 红黑树。

ConcurrentLinkedQueue

Blocking :

实现基于锁

BlockingQueue

对队列两端设置dummy结点,然后开头和结尾设置两个锁。同时可以有一个生产者和一个消费者执行。

CopyOnWrite

CopyOnWrite 之类容器修改开销相对较重

CopyOnWrite写入时拷贝的思想, 更改操作会将底层数据拷贝一份,在拷贝上执行修改,不影响其他线程的读操作,读写分离。

CopyOnWriteArrayList

HashMap的并发死链问题

HashMap在扩容的时候创建一个新的数组,容量是原数组的两倍,然后把旧数组的元素重新计算索引位置放入新数组。jdk 1.7的时候发生hash冲突后新元素在链表的头部插入,而1.8之后改为在链表的尾部插入。1.7的情况下如果两个线程都对数组进行扩容可能会导致并发死链,产生链表的循环。

 HashMap为什么用红黑树而不用B树?

红黑树在内存中比b树快, 查找的次数少。但是树的深度大,所以磁盘中不适合用红黑树。

TreeMap的底层原理

TreeMap底层是一个红黑树,根据键的自然顺序或者创建时提供的comparator进行排序

LinkedList和ArrayList的区别

插入,查找,空间有区别。

有哪些线程安全的List

Vector, Collections.SynchronizedList, CopyOnWriteList

ArrayList的底层数据结构

一个数组,初始容量为10, 每次扩容50%。 如果是以append的形式则速度还可以,但是根据index插入会很慢。

HashSet的数据结构

一个HashMap, 值为一个静态常量Object对象, PRESENT。

BlockingQueue中有哪些方法,为什么这样设计?

插入:add                offer                                        put

获取:remove          poll                                         take

        抛异常               返回错误值(超时)                阻塞

TreeMap

TreeMap的实现是红黑树,要使用TreeMap, 元素必须实现comparable接口,或者在构造时传入一个comparator。TreeSet是通过TreeSet实现的。

PriorityQueue

优先级队列使用了一个优雅且高效的数据结构,称为堆(heap)。堆是一 个可以自我调整的二叉树,对树执行添加( add) 和删除(remore) 操作, 可以让最小的元素 移动到根,而不必花费时间对元素进行排序。

需要注意的是,add之后的节点对key进行修改不会对节点重排序。

LinkedHashMap

Java集合安全的set java安全集合类_java

在一个HashMap的基础上,Entry内部有两个指针,形成双向链表。构造方法可以传入一个boolean accessOrder, true的话就是按照访问顺序排列,false是按照插入顺序排序。 

要实现LRU缓存的话去覆写 boolean : removeEldestEntry, 这个方法在put的时候会被调用,返回true则会删除末尾节点。