A popular understanding of collections and concurrent collections in Java

This is an article for shorthand and general understanding. You are welcome to point out any inaccuracies. I may not change it anyway.
Let's hang a bird's-eye view of the Java collection (top view? Frame view?).
Insert picture description here
The picture is reproduced from: Java collection knowledge points often asked in interviews (detailed)

Next, let's understand it in general

We use the Java language to develop and design classes, so we definitely need something to load the objects of these classes. So Java is designed collections and Map to do it. The collection is responsible for storing a collection of elements, and the map is responsible for storing the key/value pair mapping. However, what sets and Maps can express is very limited.
PS:Java容器里只能放对象,对于基本类型(int, long, float, double等),需要将其包装成对象类型后(Integer, Long, Float, Double等)才能放到容器里。很多时候拆包装和解包装能够自动完成。这虽然会导致额外的性能和空间开销,但简化了设计和编程。
Insert picture description here

  • We put forward requirements for the placement of elements in the collection :
    • To collect an ordered collection that allows repeated elements, so there is a List .
    • To collect collections that are unordered and do not contain repeated elements, so there is a Set .
  • We put forward requirements for access to collections :
    • The objects you want to read are entered in order and taken out in order, that is, first in, first out, so there is a Queue .
    • The objects you want to read are entered in order and taken out in reverse order, that is, first in and last out, so there is Stack .
  • We put forward requirements for the placement of elements in Map :
    • If it is placed in a hash manner, then there is a HashMap .
    • If it is placed in the way of a binary balanced tree, then there are SortedMap and TreeMap .
      Insert picture description here

Well, in the above, we mentioned a total of six types of containers, namely: List, Set, Queue, Stack, HashMap, and TreeMap.

  • For List, we put forward further requirements:
    • Implement List according to the array method, so there is ArrayList .
    • Implement List according to the two-way circular linked list , so there is LinkedList .
  • For HashMap, we put forward further requirements:
    • It can not only retain the access method of hash, but also record the insertion order of elements like LinkedList, so there is LinkedHashMap .
    • For some caching scenarios, we hope that the old data can disappear by itself, so we have WeakHashMap .
  • For TreeMap, we can't make further requirements.
  • For Set, we put forward further requirements:
    • Access data according to the Hash method, so there is HashSet , which essentially wraps HashMap .
    • Access data according to the AVL way, so there is a TreeSet , which essentially wraps the TreeMap .
    • Not only has the access method of Hash, but also can record the insertion order of elements like LinkedList, so there is LinkedHashSet , which essentially wraps LinkedHashMap .
  • For Queue, we put forward further requirements:
    • Access data according to the priority queue, so with PriorityQueue ,
    • Access data in a way that can be used as both a queue and a stack, so there is a double-ended queue: DeQueue .
    • If DeQueue is implemented as an array, then there is ArrayDeque .
  • For Stack, we can't make further requirements, but we hope you use DeQueue to implement stacks and queues.

Topic talk about common containers for interviews

  • HashMap
    • Before JDK 1.7, use head interpolation, and JDK 1.8 use tail interpolation
    • When the collision causes the linked list to be greater than TREEIFY_THRESHOLD = 8, the linked list is converted to a red-black tree
    • Before conversion, the number of buckets must be greater than 64. When it is less than 64, it will only be expanded.
    • If the length of the linked list is less than 6, turn the red-black tree back to the linked list
  • ConcurrentHashMap
    • No initialization, call the initTable() method to initialize
    • There is no hash conflict directly CAS lock-free insertion
    • Need to expand, expand first
    • If there is a hash conflict, locks are added to ensure thread safety. There are two cases: one is the form of a linked list and the insertion is directly traversed to the end, the other is the red-black tree is inserted according to the red-black tree structure
    • If the number of the linked list is greater than the threshold 8, it must first be converted into a red-black tree structure, and break enters the loop again
    • If the addition is successful, call the addCount() method to count the size, and check whether it needs expansion
    • Expansion method transfer(): The default capacity is 16, when the capacity is expanded, the capacity becomes twice the original, helpTransfer(): call multiple worker threads to help expand the capacity, so the efficiency will be higher
    • The hash value is located at the index position of the table. If it is the first node that matches, it will return. If it encounters expansion, it will call the ForwardingNode.find() method to mark the node that is expanding. Find the node and return if it matches. All of the above If it doesn't match, it traverses the nodes down and returns if it matches, otherwise it returns null at the end.

Part of the above ConcurrentHashMap content is quoted from the Internet architect

Enter the fast lane of concurrency

For the containers mentioned above, many of them cannot be used in a high-concurrency environment, and there will be thread safety issues. For commonly used containers, we have listed the concurrent version of the container under the Java Concurrency Package.

  • Let me talk about HashMap first

    • HashMap is faster, but the thread is not safe, so HashTable is introduced . Through Synchronize locking, it becomes thread safe, but at the expense of efficiency, so ConcurrentHashMap is introduced , and the security is improved by the method of segmented locking. Efficiency.
    • ConcurrentHashMap, employed in JDK 1.7 segmented locking manner; direct use of the JDK 1.8 CAS (lock-free algorithms) + synchronized
      • In JDK 1.7, segmented lock (ReentrantLock + Segment + HashEntry) is used, which is equivalent to dividing a HashMap into multiple segments and assigning a lock to each segment, which supports multi-threaded access. Lock granularity: Based on Segment, it contains multiple HashEntry.
      • CAS + synchronized + Node + red-black tree is used in JDK 1.8. Lock granularity: Node (first node) (implements Map.Entry). The lock granularity is reduced.
    • HashMap allows at most one record to have a key of null, and allows multiple records to have a value of null, while HashTable does not allow
    • HashMap needs to recalculate the hash value, while HashTable directly uses the hashCode of the object
  • And ArrayList

    • ArrayList is not thread-safe, so with Vector , it becomes thread-safe through Synchronize locking.
  • Let's talk about Queue

    • BlockingQueue、BlockingDeque、
    • ArrayBlockingQueue、LinkedBlockingDeque、LinkedBlockingQueue、
    • ConcurrentLinkedDeque 、 ConcurrentLinkedQueue 、
    • DelayQueue 、 PriorityBlockingQueue
  • Finally talk about List

    • CopyOnWriteArrayList、CopyOnWriteArraySet

Guess you like

Origin blog.csdn.net/ljfirst/article/details/105973802