• ArrayBlockingQueue和LinkedBlockingQueue


    1. ArrayBlockingQueue 数组存储,固定大小的队列。

    一个items数组,一个putIndex指针,从0到len代表已经入队了多少个元素。一个takeIndex指针,从0到len代表出队的元素位置。一个count,记录当前队列里有多少元素。

    putIndex指针入队的时候不断++,takeIndex出队的时候不断++。这个队列不是一个循环队列,判断队列空和满用count和items.length比较。

    入队:

    内部的lock锁定,如果队列满,sleep等待,当可以插入的时候,items[++putIndex]是插入元素,如果队列插入以后满了,通知出队的等待线程。

    lock.lock()

    while(count == items.length)

      lock.condition.await() //释放锁,并等待

    items[++putIndex] = element

    count++

    lock.condition.signal()

    lock.unlock()

    出队:

    内部的lock锁定,如果队列空,sleep等待,当可以出队的时候,items[++takeIndex]

    lock.lock()

    while(count == 0)

      lock.condition.await() //释放锁,并等待

    element = items[++takeIndex]

    count--

    lock.condition.signal()

    lock.unlock()

    2. LinkedBlockingQueue 链表存储,默认是无限制的队列

    区别于ArrayBlockingQueue使用数组存储,在存储上是没有限制的,不过也可以通过capacity,count配合锁来控制队列长度。

    head,last 代表链表的头尾指针,用来入队和出队,在last位置入队,head位置出队。

    takeLock和putLock来控制队列空和满时候的阻塞,这里对比ArrayBlockingQueue,出队和入队使用的是两把锁。

    capacity,count来控制队列中元素的数量,因为是用的两个锁,所以count是AtomicInteger。

    入队:

    putLock.lock()

    while (count == capacity)

      putLock.condition.await()

    last = last.next = element

    count++

    if (count + 1<capacity) //因为入队的时候有可能出队了,所以需要再检查一下,不像ArrayBlockingQueue直接signal()

      putLock.condition.signal()

    putLock.unlock()

    出队:

    takeLock.lock()

    while (count == 0)

      takeLock.condition.await()

    element = head

    head = element.next

    count--

    if (count > 1) 

      takeLock.condition.signal()

    takeLock.unlock()

     3. SynchronousQueue

    生产者和消费者直接传递数据,不对数据做缓存。生产者和消费者通过在队列里排队的方式来阻塞和唤醒。

  • 相关阅读:
    4.Docker Compose 部署 Nexus
    3.Docker Compose 部署 GitLab
    2.Docker Compose 部署应用程序
    1.Docker Compose
    6.Dockerfile 指令
    5.Dockerfile 定制镜像
    4.Docker 操作容器
    3.Docker 操作镜像
    2.Ubuntu安装 Docker
    windows快捷键
  • 原文地址:https://www.cnblogs.com/23lalala/p/5213833.html
Copyright © 2020-2023  润新知