`
wbj0110
  • 浏览: 1620713 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

java-双向并发阻塞队列 BlockingDeque

    博客分类:
  • Java
阅读更多

双向并发阻塞队列。所谓双向是指可以从队列的头和尾同时操作,并发只是线程安全的实现,阻塞允许在入队出队不满足条件时挂起线程,这里说的队列是指支持FIFO/FILO实现的链表。

 

首先看下LinkedBlockingDeque的数据结构。通常情况下从数据结构上就能看出这种实现的优缺点,这样就知道如何更好的使用工具了。

LinkedBlockingDeque类图

从数据结构和功能需求上可以得到以下结论:

  1. 要想支持阻塞功能,队列的容量一定是固定的,否则无法在入队的时候挂起线程。也就是capacity是final类型的。
  2. 既然是双向链表,每一个结点就需要前后两个引用,这样才能将所有元素串联起来,支持双向遍历。也即需要prev/next两个引用。
  3. 双向链表需要头尾同时操作,所以需要first/last两个节点,当然可以参考LinkedList那样采用一个节点的双向来完成,那样实现起来就稍微麻烦点。
  4. 既然要支持阻塞功能,就需要锁和条件变量来挂起线程。这里使用一个锁两个条件变量来完成此功能。

 

有了上面的结论再来研究LinkedBlockingDeque的优缺点。

优点当然是功能足够强大,同时由于采用一个独占锁,因此实现起来也比较简单。所有对队列的操作都加锁就可以完成。同时独占锁也能够很好的支持双向阻塞的特性。

凡事有利必有弊。缺点就是由于独占锁,所以不能同时进行两个操作,这样性能上就大打折扣。从性能的角度讲LinkedBlockingDeque要比LinkedBlockingQueue要低很多,比CocurrentLinkedQueue就低更多了,这在高并发情况下就比较明显了。

前面分析足够多的Queue实现后,LinkedBlockingDeque的原理和实现就不值得一提了,无非是在独占锁下对一个链表的普通操作。

有趣的是此类支持序列化,但是Node并不支持序列化,因此fist/last就不能序列化,那么如何完成序列化/反序列化过程呢?

清单1 LinkedBlockingDeque的序列化、反序列化

private void writeObject(java.io.ObjectOutputStream s)
    throws java.io.IOException {
    lock.lock();
    try {
        // Write out capacity and any hidden stuff
        s.defaultWriteObject();
        // Write out all elements in the proper order.
        for (Node<E> p = first; p != null; p = p.next)
            s.writeObject(p.item);
        // Use trailing null as sentinel
        s.writeObject(null);
    } finally {
        lock.unlock();
    }
}

private void readObject(java.io.ObjectInputStream s)
    throws java.io.IOException, ClassNotFoundException {
    s.defaultReadObject();
    count = 0;
    first = null;
    last = null;
    // Read in all elements and place in queue
    for (;;) {
        E item = (E)s.readObject();
        if (item == null)
            break;
        add(item);
    }
}

 

清单1 描述的是LinkedBlockingDeque序列化/反序列化的过程。序列化时将真正的元素写入输出流,最后还写入了一个null。读取的时候将所有对象列表读出来,如果读取到一个null就表示结束。这就是为什么写入的时候写入一个null的原因,因为没有将count写入流,所以就靠null来表示结束,省一个整数空间。

 

http://www.blogjava.net/xylz/archive/2010/08/18/329227.html

 
分享到:
评论

相关推荐

    62-Java并发编程实战

    62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java...

    并发-线程池和阻塞队列

    在Java编程中,"并发-线程池和阻塞队列"是两个核心概念,它们在多线程环境下处理任务调度和数据同步方面发挥着重要作用。线程池是一种管理线程资源的有效方式,而阻塞队列则常用于线程间通信和数据共享。 线程池...

    自扩充的Lock-Free并发环形队列算法

    【自扩充的Lock-Free并发环形队列算法】 在并发编程中,环形队列是一种常用的结构,尤其在多线程环境和实时系统中。它允许高效的数据传递,因为其首尾指针间的循环特性避免了数组类型的越界问题。然而,固定大小的...

    并发-线程池和阻塞队列.pdf

    Java中的ArrayBlockingQueue和LinkedBlockingQueue都是典型的阻塞队列实现。 阻塞队列为线程间通信提供了便捷的机制,可以用来协调多个线程的运行,防止多线程直接访问共享资源导致的并发问题。例如,生产者-消费者...

    swift-iOS全局并发队列管理工具

    全局并发队列是GCD提供的预定义队列,用于执行后台任务。它们是系统维护的,开发者无需创建或销毁。有四个优先级不同的全局并发队列:最高优先级、高优先级、默认优先级和低优先级。这些队列允许开发者将任务提交到...

    Java并发编程(21)并发新特性-阻塞队列和阻塞栈(含代

    在Java并发编程中,阻塞队列和阻塞栈是两个重要的并发数据结构,它们在多线程环境下的高效通信和资源管理中扮演着至关重要的角色。这些数据结构源自Java的并发包`java.util.concurrent`,是实现并发设计模式如生产者...

    fast-wait-free-queue, 并发队列实现的基准框架.zip

    fast-wait-free-queue, 并发队列实现的基准框架 快速等待空闲队列这是评估并发队列性能的基准测试框架。 目前,它包含4 个并发队列。 它们是:一个快速等待队列 wfqueueafek的Morrison和 lcrqkallimanis的Fatourou和...

    Java-高并发分布式淘淘商城.zip

    《Java高并发分布式淘淘商城系统详解》 在数字化时代,电商系统的发展日新月异,其中,"淘淘商城"作为一个模拟真实电商平台的案例,其背后的技术架构尤其值得我们深入探讨。本篇将主要围绕Java高并发分布式系统展开...

    rabbitmq-java-client-bin-3.3.4.zip

    在Java客户端中,消费者同样需要建立到服务器的连接和Channel,然后通过声明队列(Queue)并进行绑定(Binding)来监听特定的消息。 3. **交换机(Exchange)**:交换机是RabbitMQ内部的结构,它根据路由键和预定义的路由...

    Java-并发编程培训(阿里巴巴)

    Java-并发编程培训(阿里巴巴)

    计算机后端-Java-Java高并发从入门到面试教程-课程准备.zip

    在本课程"计算机后端-Java-Java高并发从入门到面试教程-课程准备"中,我们将深入探讨Java编程语言在处理高并发场景下的核心概念和技术。Java是企业级应用开发的重要选择,尤其是在大型分布式系统中,其强大的并发...

    java并发工具包详解

    8. 阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 LinkedBlockingDeque 10. 并发 Map(映射) ConcurrentMap 11. 并发导航映射 ConcurrentNavigableMap 12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 ...

    java并发工具包 java.util.concurrent中文版用户指南pdf

    8. 阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 LinkedBlockingDeque 10. 并发 Map(映射) ConcurrentMap 11. 并发导航映射 ConcurrentNavigableMap 12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 ...

    java 线程池实现多并发队列后进先出

    在"java 线程池实现多并发队列后进先出"这个主题中,我们关注的是线程池如何利用特定类型的队列来实现后进先出(LIFO,Last-In-First-Out)的行为。通常,线程池默认使用先进先出(FIFO,First-In-First-Out)的队列...

    Java-并发(Concurrent)编程

    5. **Java并发工具包(JUC)**:包括原子类、并发容器(如`ConcurrentHashMap`)、阻塞队列(如`ArrayBlockingQueue`)以及锁机制。 6. **Lock和AQS**:Lock接口提供了比`synchronized`更灵活的锁机制,而...

    计算机后端-Java-Java高并发从入门到面试教程-发课程资料.zip

    - **阻塞队列BlockingQueue**:如ArrayBlockingQueue、LinkedBlockingQueue等,理解其在生产者-消费者模型中的应用。 4. **并发工具类** - **CountDownLatch**:用于计数的同步辅助类,常用于多线程协作。 - **...

    java-并发编程思维导图xmind

    java-并发编程思维导图xmind

    Java并发工具包java.util.concurrent用户指南中英文对照阅读版.pdf

    阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 LinkedBlockingDeque 10. 并发 Map(映射) ConcurrentMap 11. 并发导航 映射 ConcurrentNavigableMap 12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 ...

    13-Java并发编程学习宝典.zip

    Java并发编程是软件开发中的重要领域,特别是在大型系统和高并发场景中不可或缺。"13-Java并发编程学习宝典.zip" 包含了一系列关于Java并发编程的学习资源,旨在帮助开发者掌握多线程编程的核心技术和最佳实践。以下...

Global site tag (gtag.js) - Google Analytics