| 在并发编程中,LinkedBlockingQueue使用的非常频繁。因其可以作为生产者消费者的中间商 |
| add() 实际上调用的是offer,区别是在队列满的时候,add会报异常 |
| offer() 对列如果满了,直接入队失败 |
| put("111") 在队列满的时候,会进入阻塞的状态 |
| remove() 直接调用poll,唯一的区别即使remove会抛出异常,而poll在队列为空的时候直接返回null |
| poll() 在队列为空的时候直接返回null |
| take() 在队列为空的时候,会进入等待的状态 |
| public class Demo2 { |
| public static void main(String[] args) throws InterruptedException { |
| LinkedBlockingQueue<String> strings = new LinkedBlockingQueue<>(); |
| |
| strings.add("111"); |
| strings.offer("111"); |
| strings.put("111"); |
| |
| String remove = strings.remove(); |
| strings.poll(); |
| strings.take(); |
| } |
| } |
| # 查看add方法 |
| public boolean add(E e) { |
| if (offer(e)) |
| return true; |
| else |
| throw new IllegalStateException("Queue full"); |
| } |
| |
| # 查看offer方法 |
| boolean offer(E e); |

| public boolean offer(E e) { |
| if (e == null) throw new NullPointerException(); |
| final AtomicInteger count = this.count; |
| if (count.get() == capacity) |
| return false; |
| final int c; |
| final Node<E> node = new Node<E>(e); |
| final ReentrantLock putLock = this.putLock; |
| putLock.lock(); |
| try { |
| if (count.get() == capacity) |
| return false; |
| enqueue(node); |
| c = count.getAndIncrement(); |
| if (c + 1 < capacity) |
| notFull.signal(); |
| } finally { |
| putLock.unlock(); |
| } |
| if (c == 0) |
| signalNotEmpty(); |
| return true; |
| } |
| |
| # 查看Node |
| static class Node<E> { |
| E item; |
| |
| |
| |
| |
| |
| |
| |
| Node<E> next; |
| |
| Node(E x) { item = x; } |
| } |
| |
| # 查看如对方法,把元素添加到队列末尾 |
| private void enqueue(Node<E> node) { |
| |
| |
| last = last.next = node; |
| } |
| public void put(E e) throws InterruptedException { |
| if (e == null) throw new NullPointerException(); |
| final int c; |
| final Node<E> node = new Node<E>(e); |
| final ReentrantLock putLock = this.putLock; |
| final AtomicInteger count = this.count; |
| putLock.lockInterruptibly(); |
| try { |
| |
| |
| |
| |
| |
| |
| |
| |
| while (count.get() == capacity) { |
| notFull.await(); |
| } |
| enqueue(node); |
| c = count.getAndIncrement(); |
| if (c + 1 < capacity) |
| notFull.signal(); |
| } finally { |
| putLock.unlock(); |
| } |
| if (c == 0) |
| signalNotEmpty(); |
| } |
| public E remove() { |
| E x = poll(); |
| if (x != null) |
| return x; |
| else |
| throw new NoSuchElementException(); |
| } |
| |
| # 查看poll实现 |
| E poll(); |

| public E poll() { |
| final AtomicInteger count = this.count; |
| if (count.get() == 0) |
| return null; |
| final E x; |
| final int c; |
| final ReentrantLock takeLock = this.takeLock; |
| takeLock.lock(); |
| try { |
| if (count.get() == 0) |
| return null; |
| x = dequeue(); |
| c = count.getAndDecrement(); |
| if (c > 1) |
| notEmpty.signal(); |
| } finally { |
| takeLock.unlock(); |
| } |
| if (c == capacity) |
| signalNotFull(); |
| return x; |
| } |
| |
| # 查看dequeue方法:将头节点移除,将下一个节点作为头节点 |
| private E dequeue() { |
| |
| |
| Node<E> h = head; |
| Node<E> first = h.next; |
| h.next = h; |
| head = first; |
| E x = first.item; |
| first.item = null; |
| return x; |
| } |
| public E take() throws InterruptedException { |
| final E x; |
| final int c; |
| final AtomicInteger count = this.count; |
| final ReentrantLock takeLock = this.takeLock; |
| takeLock.lockInterruptibly(); |
| try { |
| while (count.get() == 0) { |
| notEmpty.await(); |
| } |
| x = dequeue(); |
| c = count.getAndDecrement(); |
| if (c > 1) |
| notEmpty.signal(); |
| } finally { |
| takeLock.unlock(); |
| } |
| if (c == capacity) |
| signalNotFull(); |
| return x; |
| } |
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术