1. SynchronousQueue简介
SynchronousQueue是无界的,是一种无缓冲的阻塞队列,插入操作必须等待令一个线程取数据,反之亦然(SynchronousQueue是线程安全的,是阻塞的)。同步队列没有任何内部容量,甚至连一个队列的容量都没有。
PS:什么是线程安全?
线程安全就是说多线程访问同一代码,不会产生不确定的结果。
声明一个SynchronousQueue有两种不同的方式,它们之间有着不太一样的行为。
公平模式:
SynchronousQueue会采用公平锁,并配合一个FIFO队列来阻塞多余的生产者和消费者,从而体系整体的公平策略;
非公平模式(SynchronousQueue默认):
SynchronousQueue采用非公平锁,同时配合一个LIFO队列来管理多余的生产者和消费者,而后一种模式,如果生产者和消费者的处理速度有差距,则很容易出现饥渴的情况,即可能有某些生产者或者是消费者的数据永远都得不到处理。
注意:
(1)不能在同步队列上进行 peek,因为仅在试图要取得元素时,该元素才存在;
(2)除非另一个线程试图移除某个元素,否则也不能(使用任何方法)添加元素;
(3)不能迭代队列
(4)该队列的头是尝试添加到队列的首个已排队插入线程的元素;如果没有这样的已排队线程,则没有可用于移除的元素并且pool方法将返回null
(5)不允许 null 元素
对于其他 Collection 方法(例如 contains)SynchronousQueue 作为一个空集合。
(6)同步队列类似于传递性的设计,即一个线程中运行的对象要将某些信息/事件/任务传递给另一个线程中运行的对象-->同步
(7)SynchronousQueue构造方法中可指定fairness的策略.如果fair,则等待线程以FIFO的顺序竞争访问;否则顺序是未指定的
2. SynchronousQueue方法
iterator() 永远返回空,因为里面没东西。
peek() 永远返回null。
put() 往queue放进去一个element以后就一直wait直到有其他thread进来把这个element取走。
offer() 往queue里放一个element后立即返回,如果碰巧这个element被另一个thread取走了,offer方法返回true,认为offer成功;否则返回false。
offer(2000, TimeUnit.SECONDS) 往queue里放一个element但是等待指定的时间后才返回,返回的逻辑和offer()方法一样。
take() 取出并且remove掉queue里的element(认为是在queue里的。。。),取不到东西他会一直等。
poll() 取出并且remove掉queue里的element(认为是在queue里的。。。),只有到碰巧另外一个线程正在往queue里offer数据或者put数据的时候,该方法才会取到东西。否则立即返回null。
poll(2000, TimeUnit.SECONDS) 等待指定的时间然后取出并且remove掉queue里的element,其实就是再等其他的thread来往里塞。
isEmpty()永远是true。
remainingCapacity() 永远是0。
remove()和removeAll() 永远是false。
3. 后记
(1)SynchronousQueue中没有空间,那么资源会会以最快的方式从生产者传递给消费者。
(2)SynchronousQueue中维护着生产者和消费者线程队列,既然有队列,同样就有公平性和非公平性特性,公平性保证正在等待的插入线 程或者移除线程以FIFO的顺序传递资源
4. 参考文献
[1]http://blog.csdn.net/mn11201117/article/details/8671497
[2]http://wear.techbrood.com/reference/java/util/concurrent/SynchronousQueue.html
[3]http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html

SynchronousQueue是一个无界但无内部容量的阻塞队列,插入操作必须等待其他线程取走数据。它是线程安全的,分为公平模式和非公平模式。公平模式下,线程按FIFO顺序竞争资源;非公平模式下,顺序不确定,可能导致饥饿现象。SynchronousQueue不支持peek、迭代、添加null元素和有容量的方法,其isEmpty始终为true,remainingCapacity始终为0。它常用于高效传递资源给消费者。
2253

被折叠的 条评论
为什么被折叠?



