【Java并发编程】4、JDK7中TransferQueue的使用以及TransferQueue与SynchronousQueue的差别
转自:http://blog.csdn.net/aitangyong/article/details/46472643
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.
- *
- * <p>More precisely, transfers the specified element immediately
- * if there exists a consumer already waiting to receive it (in
- * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
- * otherwise returning {@code false} without enqueuing the element.
- *
- * @param e the element to transfer
- * @return {@code true} if the element was transferred, else
- * {@code false}
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this queue
- */
- boolean tryTransfer(E e);
- /**
- * Transfers the element to a consumer, waiting if necessary to do so.
- *
- * <p>More precisely, transfers the specified element immediately
- * if there exists a consumer already waiting to receive it (in
- * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
- * else waits until the element is received by a consumer.
- *
- * @param e the element to transfer
- * @throws InterruptedException if interrupted while waiting,
- * in which case the element is not left enqueued
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this queue
- */
- void transfer(E e) throws InterruptedException;
- /**
- * Transfers the element to a consumer if it is possible to do so
- * before the timeout elapses.
- *
- * <p>More precisely, transfers the specified element immediately
- * if there exists a consumer already waiting to receive it (in
- * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
- * else waits until the element is received by a consumer,
- * returning {@code false} if the specified wait time elapses
- * before the element can be transferred.
- *
- * @param e the element to transfer
- * @param timeout how long to wait before giving up, in units of
- * {@code unit}
- * @param unit a {@code TimeUnit} determining how to interpret the
- * {@code timeout} parameter
- * @return {@code true} if successful, or {@code false} if
- * the specified waiting time elapses before completion,
- * in which case the element is not left enqueued
- * @throws InterruptedException if interrupted while waiting,
- * in which case the element is not left enqueued
- * @throws ClassCastException if the class of the specified element
- * prevents it from being added to this queue
- * @throws NullPointerException if the specified element is null
- * @throws IllegalArgumentException if some property of the specified
- * element prevents it from being added to this queue
- */
- boolean tryTransfer(E e, long timeout, TimeUnit unit)
- throws InterruptedException;
- /**
- * Returns {@code true} if there is at least one consumer waiting
- * to receive an element via {@link #take} or
- * timed {@link #poll(long,TimeUnit) poll}.
- * The return value represents a momentary state of affairs.
- *
- * @return {@code true} if there is at least one waiting consumer
- */
- boolean hasWaitingConsumer();
- /**
- * Returns an estimate of the number of consumers waiting to
- * receive elements via {@link #take} or timed
- * {@link #poll(long,TimeUnit) poll}. The return value is an
- * approximation of a momentary state of affairs, that may be
- * inaccurate if consumers have completed or given up waiting.
- * The value may be useful for monitoring and heuristics, but
- * not for synchronization control. Implementations of this
- * method are likely to be noticeably slower than those for
- * {@link #hasWaitingConsumer}.
- *
- * @return the number of consumers waiting to receive elements
- */
- int getWaitingConsumerCount();
- }
可以看到TransferQueue同时也是一个阻塞队列,它具备阻塞队列的所有特性,主要介绍下上面5个新增API的作用。
1.transfer(E e)若当前存在一个正在等待获取的消费者线程,即立刻将e移交之;否则将元素e插入到队列尾部,并且当前线程进入阻塞状态,直到有消费者线程取走该元素。
- public class TransferQueueDemo {
- private static TransferQueue<String> queue = new LinkedTransferQueue<String>();
- public static void main(String[] args) throws Exception {
- new Productor(1).start();
- Thread.sleep(100);
- System.out.println("over.size=" + queue.size());
- }
- static class Productor extends Thread {
- private int id;
- public Productor(int id) {
- this.id = id;
- }
- @Override
- public void run() {
- try {
- String result = "id=" + this.id;
- System.out.println("begin to produce." + result);
- queue.transfer(result);
- System.out.println("success to produce." + result);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
可以看到生产者线程会阻塞,因为调用transfer()的时候并没有消费者在等待获取数据。队列长度变成了1,说明元素e没有移交成功的时候,会被插入到阻塞队列的尾部。
2.tryTransfer(E e)若当前存在一个正在等待获取的消费者线程,则该方法会即刻转移e,并返回true;若不存在则返回false,但是并不会将e插入到队列中。这个方法不会阻塞当前线程,要么快速返回true,要么快速返回false。
3.hasWaitingConsumer()和getWaitingConsumerCount()用来判断当前正在等待消费的消费者线程个数。
4.tryTransfer(E e, long timeout, TimeUnit unit) 若当前存在一个正在等待获取的消费者线程,会立即传输给它; 否则将元素e插入到队列尾部,并且等待被消费者线程获取消费掉。若在指定的时间内元素e无法被消费者线程获取,则返回false,同时该元素从队列中移除。
- public class TransferQueueDemo {
- private static TransferQueue<String> queue = new LinkedTransferQueue<String>();
- public static void main(String[] args) throws Exception {
- new Productor(1).start();
- Thread.sleep(100);
- System.out.println("over.size=" + queue.size());//1
- Thread.sleep(1500);
- System.out.println("over.size=" + queue.size());//0
- }
- static class Productor extends Thread {
- private int id;
- public Productor(int id) {
- this.id = id;
- }
- @Override
- public void run() {
- try {
- String result = "id=" + this.id;
- System.out.println("begin to produce." + result);
- queue.tryTransfer(result, 1, TimeUnit.SECONDS);
- System.out.println("success to produce." + result);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
第一次还没到指定的时间,元素被插入到队列中了,所有队列长度是1;第二次指定的时间片耗尽,元素从队列中移除了,所以队列长度是0。
这篇文章中讲了SynchronousQueue的使用方式,可以看到TransferQueue也具有SynchronousQueue的所有功能,但是TransferQueue的功能更强大。这篇文章中提到了这2个API的区别:
- TransferQueue is more generic and useful than SynchronousQueue however as it allows you to flexibly decide whether to use normal BlockingQueue
- semantics or a guaranteed hand-off. In the case where items are already in the queue, calling transfer will guarantee that all existing queue
- items will be processed before the transferred item.
- SynchronousQueue implementation uses dual queues (for waiting producers and waiting consumers) and protects both queues with a single lock. The
- LinkedTransferQueue implementation uses CAS operations to form a nonblocking implementation and that is at the heart of avoiding serialization
- bottlenecks.
【Java并发编程】4、JDK7中TransferQueue的使用以及TransferQueue与SynchronousQueue的差别的更多相关文章
- Java并发编程(3) JUC中的锁
一 前言 前面已经说到JUC中的锁主要是基于AQS实现,而AQS(AQS的内部结构 .AQS的设计与实现)在前面已经简单介绍过了.今天记录下JUC包下的锁是怎么基于AQS上实现的 二 同步锁 同步锁不 ...
- Java并发编程:JDK中的阻塞队列
上次我们讲了一些常用的4个阻塞队列,但是在JDK中还提供了其他的一些阻塞队列.这篇文章将全面介绍一下JDK中的所有阻塞队列,并比较他们的区别. JDK7提供了7个阻塞队列.分别是 ArrayBlock ...
- 整理一下《java并发编程实战》中的知识点
分工.同步.互斥的历史由来 分工:单道.多道.分时 同步:线程通信(组织编排任务) 互斥:因(多线程访问共享资源)果(串行化共享资源的访问) 1切都是为了提高性能 2.可见性.原子性.有序性 可见性: ...
- Java并发编程面试题 Top 50 整理版
本文在 Java线程面试题 Top 50的基础上,对部分答案进行进行了整理和补充,问题答案主要来自<Java编程思想(第四版)>,<Java并发编程实战>和一些优秀的博客,当然 ...
- Java并发编程73道面试题及答案 —— 面试稳了
今天主要整理一下 Java 并发编程在面试中的常见问题,希望对需要的读者有用. 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任 ...
- Java并发编程学习路线(转)
以前特地学过并发编程,但是没怎么学进去,不太喜欢.最近发现,作为一个资深工程师,却没有完整深入系统的学习过,而反是现在的BAT大并发是必须的,感觉甚是惭愧. 故找了一片学习文章,如下,准备集中一段时间 ...
- Java并发编程学习路线
一年前由于工作需要从微软技术栈入坑Java,并陆陆续续做了一个Java后台项目,目前在搞Scala+Java混合的后台开发,一直觉得并发编程是所有后台工程师的基本功,所以也学习了小一年Java的并发工 ...
- Java 并发编程-不懂原理多吃亏(送书福利)
作者 | 加多 关注阿里巴巴云原生公众号,后台回复关键字"并发",即可参与送书抽奖!** 导读:并发编程与 Java 中其他知识点相比较而言学习门槛较高,从而导致很多人望而却步.但 ...
- java并发编程之美-阅读记录1
1.1什么是线程? 在理解线程之前先要明白什么是进程,因为线程是进程中的一个实体.(线程是不会独立存在的) 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程中的 ...
- Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理
Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...
随机推荐
- 【转】老左常用国内/国外VPS推荐
原文:http://www.laozuo.org 老左从使用虚拟主机到VPS,至今也用过不少的商家产品,比如在"TOP10美国虚拟主机/网站空间推荐"有分享目前和曾经使用的虚拟主机 ...
- OCP考试062题库出现大量新题-19
choose three Which three statements are true about Oracle Data Pump? A) Oracle Data Pump export and ...
- dubbo+zookeeper注册服务报错问题:No service registed on zookeeper
2019-04-04 11:23:40,372 ERROR [tomcat-threads--1] (com.bill99.dolphin.controller.ExceptionController ...
- ASP.NETCore学习记录(一)
ASP.NETCore学习记录(一) asp.net core介绍 Startup.cs ConfigureServices Configure 0. ASP.NETCore 介绍 ASP.N ...
- Math.log()对数的妙用
###对数log 的妙用... formatBytes(bytes) { if (bytes === '0' || isNaN(bytes)) return ''; var s = ['Bytes', ...
- JobScheduler android任务调度处理组件(类似QuartZ)
JobScheduler是Android L(API21)新增的特性,用于定义满足某些条件下(电量,网络,时间,屏幕熄/亮 ,设备是否空闲 等)执行的任务.它的宗旨是把一些不是特别紧急的任务放到更合适 ...
- Scanner的概述与String类的构造和使用_DAY12
1:Scanner的概述(理解) 1)Scanner是JDK5以后出现的方便我们从键盘接受数据的类. 2)Scanner的构造格式: Scanner sc = new Scanner(System.i ...
- 自定义 Scrapy 爬虫请求的 URL
之前使用 scrapy 抓取数据的时候 ,默认是在逻辑中判断是否执行下一次请求 def parse(self): # 获取所有的url,例如获取到urls中 for url in urls: yiel ...
- Java总结:开发环境
更多请查看在线文集:http://android.52fhy.com/java/index.html Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言 ...
- Chapter 2 Open Book——25
"My name is Edward Cullen," he continued. "I didn't have a chance to introduce myself ...