SynchronousQueue

SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除操作take,反过来也一样。

不像ArrayBlockingQueue或LinkedListBlockingQueue,SynchronousQueue内部并没有数据缓存空间,你不能调用peek()方法来看队列中是否有数据元素,因为数据元素只有当你试着取走的时候才可能存在,不取走而只想偷窥一下是不行的,当然遍历这个队列的操作也是不允许的。队列头元素是第一个排队要插入数据的线程,而不是要交换的数据。数据是在配对的生产者和消费者线程之间直接传递的,并不会将数据缓冲数据到队列中。可以这样来理解:生产者和消费者互相等待对方,握手,然后一起离开。

阻塞算法实现:

  阻塞算法实现通常在内部采用一个锁来保证多个线程中的put()和take()方法是串行执行的。采用锁的开销是比较大的,还会存在一种情况是线程A持有线程B需要的锁,B必须一直等待A释放锁,即使A可能一段时间内因为B的优先级比较高而得不到时间片运行。所以在高性能的应用中我们常常希望规避锁的使用。

时间: 2024-10-09 23:27:40

SynchronousQueue的相关文章

【死磕Java并发】-----J.U.C之阻塞队列:SynchronousQueue

[注]:SynchronousQueue实现算法看的晕乎乎的,写了好久才写完,如果当中有什么错误之处,忘各位指正 作为BlockingQueue中的一员,SynchronousQueue与其他BlockingQueue有着不同特性: 没有容量.与其他BlockingQueue不同,是一个不存储元素的BlockingQueue.每一个put操作必须要等待一个take操作,否则不能继续添加元素,反之亦然. 因为没有容量,所以对应 peek, contains, clear, isEmpty - 等方

似懂非懂的SynchronousQueue和长度为1的BlockingQueue

阅读ArrayBlockingQueue源码,很容易知道有界阻塞队列的长度至少为1,也就是至少能缓存下一个数据.SynchronousQueue的javadoc文档提到A synchronous queue does not have any internal capacity, not even a capacity of one.也就说同步队列的容量是0,不会缓存数据. 长度为1的阻塞队列和SynchronousQueue都能够实现以下效果:插入数据的线程和获取数据的线程,交替执行. pub

Java 7中的TransferQueue 以及 SynchronousQueue

Java7中加入了JSR 166y规范对集合类和并发类库的改进.其中的一项是增加了接口TransferQueue和其实现类LinkedTransferQueue. TransferQueue继承了BlockingQueue(BlockingQueue又继承了Queue)并扩展了一些新方法.BlockingQueue(和Queue)是Java 5中加入的接口,它是指这样的一个队列:当生产者向队列添加元素但队列已满时,生产者会被阻塞:当消费者从队列移除元素但队列为空时,消费者会被阻塞. Transf

SynchronousQueue应用

SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加:可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()方法永远返回是true,remainingCapacity() 方法永远返回是0,remove()和removeAll() 方法永远返回是false,iterator()方法永远返回空,peek()方法永远返回null. 声明一个SynchronousQue

[源码]源代码解析 SynchronousQueue

简析SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue 三者都是blockingQueue. LinkedBlockingQueue,ArrayBlockingQueue 有界,默认是Integer.Max; SynchronousQueue没什么界不界的概念.之所以这么说.是因为它的操作必须成对. 注记方案: oppo(oppo手机)是一对,offer和pool不阻塞 ppt是一对.put和take都阻塞. 1. 里面没有任何数据.调

【实战Java高并发程序设计 7】让线程之间互相帮助--SynchronousQueue的实现

[实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象引用:AtomicStampedReference [实战Java高并发程序设计 4]数组也能无锁:AtomicIntegerArray [实战Java高并发程序设计 5]让普通变量也享受原子操作 [实战Java高并发程序设计6]挑战无锁算法:无锁的Vector实现 在对线程池的介绍中,提到了一个非

java concurrent 之 SynchronousQueue

Java 6的并发编程包中的SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除操作take,反过来也一样. 不像ArrayBlockingQueue或LinkedListBlockingQueue,SynchronousQueue内部并没有数据缓存空间,你不能调用peek()方法来看队列中是否有数据元素,因为数据元素只有当你试着取走的时候才可能存在,不取走而只想偷窥一下是不行的,当然遍历这个队列的操作也是不允许的.队

JDK7中TransferQueue的使用以及TransferQueue与SynchronousQueue的差别

JDK7对JDK5中的J.U.C并发工具进行了增强,其中之一就是新增了TransferQueue.java并发相关的JSR规范,可以查看Doug Lea维护的blog.现在简单介绍下这个类的使用方式. public interface TransferQueue<E> extends BlockingQueue<E> { /** * Transfers the element to a waiting consumer immediately, if possible. * * &

多线程-BlockingQueue,Array[Linked]BlockingQueue,DelayQueue,PriorityBlockingQueue,SynchronousQueue

阻塞场景 BlockingQueue阻塞队列,阻塞的情况主要有如下2种: 1. 当队列满了,进行入队操作阻塞 2. 当队列空了,进行出队操作阻塞 阻塞队列主要用在生产者/消费者模式中,下图展示了一个线程生产,一个线程消费的场景: BlockingQueue接口 操作 抛异常 特殊值 阻塞 超时 插入 add(o) offer(o) put(o) offer(o,timeout,unit) 删除 remove(o) poll() take() poll(timeout,unit) 1. 抛出异常: