• LinkedBlockingQueue有界队列


    初始化

      创建的时候,实际就是指定了队列大小 capacity,然后队列node其实就是个单向列表结构,item 是当前元素,next 是下一个元素的引用。默认head指针和last指针都是指向这个空节点。ps: 是不是有点责任链模式的感觉呢。

    put

    put 从队列尾部插入节点

      1. 首先也是获取到了 ReentrantLock 锁 ,进行 putLock 加锁。
      2. 添加元素之前,先 while (count.get() == capacity) 判断一下,count 是队列中的个数,capacity 是指定的最大个数。相等就说明队列满了,那当前线程就要park挂起释放锁。
      3. enqueue(node) 这个是核心,走到这里说明可以添加元素了。 "last = last.next = node;" 这行代码的意思就是先将 last.next 的指针指向node,然后再把 last 也指向它,说明是最后一个元素(初始化的时候我们把 head last 都是指向null这个头节点的嘛,现在头节点还是保持不动)。
      4. c 是此次put前的元素个数,然后count自增1了。c + 1 < capacity 说明队列没有满,也尝试去唤醒阻塞的队列 (这种代码确实可读性不太好,像hashmap里面也是大量这样的代码)。
      5. c == 0 ,表示之前队列位空,说明可能有线程执行take操作被阻塞住了

    take

    take 从头部弹出节点

      1. 先获取到 ReentrantLock 锁 ,进行 takeLock 加锁。
      2. while (count.get() == 0)那就说明队列中没有元素,然后把自己挂起来一直等待(前面不是说了put也会唤醒等待的元素嘛,那个时候就会唤醒这个线程)。
      3. dequeue();就是弹出第一个节点
      4. c = count.getAndDecrement(); 首先是c = count的,然后 count-1 ,也就是说 c-count=1
      5. c > 1,也就是说task之前起码是有2个线程等待的,现在 dequeue() 之后起码还有一条数据,那就去唤醒线程
      6. c == capacity,就是说 take 之前满了,那就很可能有人put的时候阻塞了,现在就去尝试唤醒它

     

  • 相关阅读:
    PHP中使用CURL实现GET和POST请求
    PHP 正则表达式匹配函数 preg_match 与 preg_match_all
    微信跳转黑科技:微信跳转技术让微信电商从此不缺流量
    PHP通过get方法获得form表单数据方法总结
    php获取微信基础接口凭证Access_token
    PHP命名空间与自动加载类详解
    PHP如何搭建百度Ueditor富文本编辑器
    PHP调用微博接口实现微博登录的方法示例
    PHP常用日期加减计算方法实例
    微信公众平台---带参数二维码生成和扫描事件
  • 原文地址:https://www.cnblogs.com/wlwl/p/15057170.html
Copyright © 2020-2023  润新知