HashMap
Index calculation: hashCode & (length-1), & bitwise AND operation, the same bit is a binary 1, which is only 1 bit
JDK1.7 JDK1.8 HashMap with the differences: JDK1.8 element when put, if the calculated chain length in the obtained index reaches 8:00 (the current count to be applied to the rear elements of the list), the list is converted into red black tree to improve search efficiency
ConcurrentHashMap
HashMap thread-safe
JDK1.7 ConcurrentHashMap HashTable composed of multiple, concurrent HashTable there are several levels of concurrencyLevel is a few default 16, which is called the segment lock,
ConcurrentSkipListMap/TreeMap
TreeMap except that the HashMap, TreeMap key of lexicographically ordered (ascending), can be achieved by sorting logic Comparator
TreeMap thread-safe, use ConcurrentSkipListMap guarantee thread safety
ArrayList
Non-thread-safe
CopyOnWriteArrayList
Thread-safe,
However, the array will be copied, at a certain time doubling the amount of data that cause memory overflow, data overload situation NA
Read the newly written data will be delayed, because the reference to the new needs of the array from the old array array
HashSet
HashMap if you encounter the same Key Value value will be overridden to ensure the HashMap Key is not repeated.
HashSet <T> i.e. HashMap This feature ensures the use of elements in the set Set (KEY) is not repeated, it is not concerned with the value of Value.
CopyOnWriteArraySet
Write time will determine whether the array already exists, if there is no longer write, and other characteristics of the same CopyOnWriteArrayList
ConcurrentSkipListSet
The principle of non-repetition jump table with ConcurrentSkipListMap, KEY and orderly
QUEUE queue
ArrayBlockingQueue
线程安全,数组实现,ReentrantLock锁,只有一把锁,take() 和 put() 互斥,加的是同一把锁;
构造函数制定队列长度capacity,利用参数count记录队列中元素数量,count=capacity时put操作阻塞,count=0时take操作阻塞,底层唤醒其实是利用condition的2个队列实现,参照1.3.1 Lock利用condition实现的阻塞队列;
put和take时利用takeIndex和putIndex记录下一个操作应该放到那个位置或从哪个位置取;
循环数组实现:当putIndex达到capacity时,takeIndex并不是+1,而是变成0,即下一个put操作会将元素放到队列头部;takeIndex原理相同
LinkedBlockingQueue
线程安全,链表实现,有读锁和写锁2把锁,读和写操作加的是不同的锁,互不干扰,提高了读写性能
ConcurrentLinkedQueue
线程安全,并发度高,非阻塞队列,无锁,没有take() 和 put()这2个阻塞方法
利用CAS操作,采用自旋的方式将元素添加到链表尾部 或 将链表头部替换为null
SynchronousQueue
不常用
package com.study.list_set_queue.queue; import java.util.concurrent.SynchronousQueue; /* 1、take会阻塞,直到取到元素 2、put时会阻塞,直到被get 3、若没有take方法阻塞等待,offer的元素可能会丢失 4、poll取不到元素,就返回null,如果正好有put被阻塞,可以取到 5、peek 永远只能取到null,不能让take结束阻塞 */ public class Demo2_SyncQueueTest { static SynchronousQueue<String> syncQueue = new SynchronousQueue<>(); //put时会阻塞,直到被get public static void test01() throws InterruptedException { new Thread(){ @Override public void run() { try { Thread.sleep(3000L); System.out.println(syncQueue.poll()); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); System.out.println("begain to put..."); syncQueue.put("put_element"); System.out.println("put done..."); } //3、若没有take方法阻塞等待,offer的元素可能会丢失 public static void test02() throws InterruptedException { syncQueue.offer("offered_element"); System.out.println(syncQueue.poll()); } //4、poll取不到元素,就返回null,如果正好有put被阻塞,可以取到 public static void test03() throws InterruptedException { /* new Thread(){ @Override public void run() { try { syncQueue.put("put_element"); } catch (InterruptedException e) { e.printStackTrace(); } } }.start();*/ Thread.sleep(200L); Object obj = syncQueue.poll(); System.out.println(obj); } //peek 永远只能取到null,不能让take结束阻塞 public static void test04() throws InterruptedException { new Thread(){ @Override public void run() { try { syncQueue.put("put_element"); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); Thread.sleep(200L); Object obj = syncQueue.peek(); System.out.println(obj); } public static void main(String args[]) throws InterruptedException { test02(); } }
PriorityBlockingQueue
优先级队列,可以通过比较器对入队列的元素进行排序存储,进而改变出队列顺序
package com.study.list_set_queue.queue; import java.util.Comparator; import java.util.concurrent.PriorityBlockingQueue; public class Demo4_PriorityBlockingQueue3 { public static void main(String args[]) { PriorityBlockingQueue<Student> queue = new PriorityBlockingQueue<>(5, new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { int num1 = o1.age; int num2 = o2.age; if (num1 > num2) return 1; else if (num1 == num2) return 0; else return -1; } }); queue.put(new Student(10, "enmily")); queue.put(new Student(20, "Tony")); queue.put(new Student(5, "baby")); for (; queue.size() > 0;) { try { System.out.println(queue.take().name); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Student { public int age; public String name; public Student(int age, String name) { this.age = age; this.name = name; } }