Update 集合源码.md

master
Omooo 5 years ago
parent b0f0586fcf
commit 3d17dfb3a5
  1. 4
      blogs/Java/口水话/集合源码.md

@ -142,7 +142,7 @@ ConcurrentHashMap 的 get 和 HashMap 基本无差。
#### LinkedBlockingQueue #### LinkedBlockingQueue
LinkedBlockingQueue 即链表阻塞队列,它实现了 BlockingQueue 接口,BlockingQueue 在 Queue 的基础上加上了阻塞的概念;链表维护了先入先出的队列,新元素被放在队尾,获取元素从队头拿;当我们调用 put 时,队列满了就一直阻塞,也可以调用 offer 阻塞一段时间返回 false,调用 take 时,如果队列为空也是一直阻塞,也可以调用 poll 阻塞一段时间返回 null。 LinkedBlockingQueue 即链表阻塞队列,它实现了 BlockingQueue 接口,BlockingQueue 在 Queue 的基础上加上了阻塞的概念;链表维护了先入先出的队列,新元素被放在队尾,获取元素从队头拿;当我们调用 put 时,队列满了就一直阻塞,在阻塞时被其他线程设置了中断标志,则被阻塞的线程会抛出 InterruptedException 异常而返回,也可以调用非阻塞的 offer 方法,如果队列满了就放弃当前元素返回 false;调用 take 时,如果队列为空也是一直阻塞,也可以调用非阻塞的 poll 方法,如果队列为空就直接返回 null。
LinkedBlockingQueue 内部构成简单来说,可以分为三个部分:链表存储 + 锁 + 迭代器。它内部有两把 ReentrantLock 锁,分别是 put 锁和 take 锁,保证了队列操作的线程安全,设计两把锁,是为了 put 和 take 两种操作可以同时进行,互不影响。 LinkedBlockingQueue 内部构成简单来说,可以分为三个部分:链表存储 + 锁 + 迭代器。它内部有两把 ReentrantLock 锁,分别是 put 锁和 take 锁,保证了队列操作的线程安全,设计两把锁,是为了 put 和 take 两种操作可以同时进行,互不影响。
@ -150,6 +150,8 @@ LinkedBlockingQueue 内部构成简单来说,可以分为三个部分:链表
在 take 时,也是先加 take 锁,然后判断队列是否为空,为空就无限等待,否则就删除链表头节点返回,如果这时队列没有满,就唤醒一个 put 的等待线程,最后在解锁。 在 take 时,也是先加 take 锁,然后判断队列是否为空,为空就无限等待,否则就删除链表头节点返回,如果这时队列没有满,就唤醒一个 put 的等待线程,最后在解锁。
在 remove 时会获取双重锁,获取后,其他线程进行入队或出队操作都会被阻塞挂起,然后遍历队列找到要删除的元素删除,找到了就删除并唤醒一个阻塞的 put 线程,否则返回 false。
LinkedBlockingQueue 主要用在线程池中,当我们使用 Executors 的 newFixedThreadPool 或 newSingleThreadPool 创建线程池时,阻塞队列用的就是 LinkedBlockingQueue,但是通常我们不建议这样直接使用 Executors 创建线程池,因为 LinkedBlockingQueue 的默认队列大小是 Integer.MAX_VALUE,可能会爆内存。 LinkedBlockingQueue 主要用在线程池中,当我们使用 Executors 的 newFixedThreadPool 或 newSingleThreadPool 创建线程池时,阻塞队列用的就是 LinkedBlockingQueue,但是通常我们不建议这样直接使用 Executors 创建线程池,因为 LinkedBlockingQueue 的默认队列大小是 Integer.MAX_VALUE,可能会爆内存。
在 Android 中,AsyncTask 在核心线程池不够用的情况下触发任务拒绝策略时,会用到 LinkedBlockingQueue。 在 Android 中,AsyncTask 在核心线程池不够用的情况下触发任务拒绝策略时,会用到 LinkedBlockingQueue。

Loading…
Cancel
Save