线程安全集合

我们之前了解的集合大多是线程不安全的,比如说 ArrayList,HashSet,HashMap,但它们往往高效率。
也有一些线程安全的集合,如 Vector,HashTable 但大多都是基于 sychronized 锁控制机制,性能很低。

如果既保证线程安全,执行效率又高,就可考虑下JUC下的集合类,如:
ArrayList 对应的高并发类是 CopyOnWriteArrayList,
HashSet 对应的高并发类是 CopyOnWriteArraySet,
HashMap 对应的高并发类是 ConcurrentHashMap。

此外还有其他相关的线程安全类
java.util.concurrent.ConcurrentSkipListMap 可以调过执行储存位置的 Map java.util.concurrent.ConcurrentSkipListSet 可以调过执行储存位置的 Set

阻塞队列

Java 中总的算起来有 8 种阻塞队列。
image.png
通过继承 BlockingQueue 接口实现。

ArrayBlockingQueue 数组队列,我们在 使用 ReentrantLock 和 Condition 实现一个阻塞队列 看过了 JDK 写的一个例子,就是该类的基本原理和实现。
LinkedBlockingDeque 是一个双向链表的队列。常用于 “工作窃取算法”。
DelayQueue 是一个支持延时获取元素的无界阻塞队列。内部用 PriorityQueue 实现。
PriorityBlockingQueue 是一个支持优先级的无界阻塞队列,和 DelayWorkQueue 类似。
LinkedTransferQueue 是 SynchronousQueue 和 LinkedBlockingQueue 合体,性能比 LinkedBlockingQueue 更高(没有锁操作),比 SynchronousQueue能存储更多的元素。

ArrayBlockingQueue

SynchronousQueue

这个消息队列比较特俗,不存储元素的阻塞队列,也即单个元素的消息队列。

测试案例

  1. public class SynchronousQueueTest00 {
  2. public void test00() {
  3. BlockingQueue<Integer> queue = new SynchronousQueue<>();
  4. new Thread(new Runnable() {
  5. @SneakyThrows
  6. @Override
  7. public void run() {
  8. System.out.println(Thread.currentThread().getName() + "\t 发送一个数值 1");
  9. queue.put(1);
  10. System.out.println(Thread.currentThread().getName() + "\t 发送一个数值 2");
  11. queue.put(2);
  12. System.out.println(Thread.currentThread().getName() + "\t 发送一个数值 3");
  13. queue.put(3);
  14. }
  15. }, "AA").start();
  16. new Thread(new Runnable() {
  17. @SneakyThrows
  18. @Override
  19. public void run() {
  20. Thread.sleep(3000);
  21. Integer num = queue.take();
  22. System.out.println("接受一个数值:" + num);
  23. Thread.sleep(3000);
  24. num = queue.take();
  25. System.out.println("接受一个数值:" + num);
  26. Thread.sleep(3000);
  27. num = queue.take();
  28. System.out.println("接受一个数值:" + num);
  29. }
  30. }, "BB").start();
  31. }
  32. public static void main(String[] args) {
  33. SynchronousQueueTest00 test00 = new SynchronousQueueTest00();
  34. test00.test00();
  35. }
  36. }

运行结果
image.png

LinkedTransferQueue

LinkedTransferQueue 通过追加字节能优化性。

参考资料

为什么 JUC 下的集合类是线程安全的?
并发编程—— LinkedTransferQueue