【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 ...
随机推荐
- 可编辑树Ztree的使用(包括对后台数据库的增删改查)
找了很多网上关于Ztree的例子和代码才搞定. 首先,关于Ztree的代码不介绍了,网上下载之后,引用下列四个文件就能使用了. 1.关于配置选项.主要通过回调函数来实现向后台发送数据,实现增删改查. ...
- 简单的C# Socket通信实例
一.套接字(socket)概念 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本 ...
- MariaDB 主从同步与热备(14)
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可MariaDB的目的是完全兼容MySQL,包括API和命令行,MySQL由于现在闭源了,而能轻松成为MySQ ...
- XSS 跨站脚本攻击 的防御解决方案
虽然说在某些特殊情况下依然可能会产生XSS,但是如果严格按照此解决方案则能避免大部分XSS攻击. 原则:宁死也不让数据变成可执行的代码,不信任任何用户的数据,严格区数据和代码. XSS的演示 Exam ...
- sublime text 文件打开时回调一些函数
需求:公司服务端脚本以 .s 结尾的文件,也按 js 语法识别,方便查看函数定义. 每次都 ss:js 比较麻烦,所以写个插件. import sublime, sublime_plugin clas ...
- Upgrade Win10
Internal deployment of Windows 10 Enterprise is currently underway as a phased deployment. Watch you ...
- IQueryable与IEnumerable
IEnumerable: 从服务器处取回所有数据,在客户端根据过滤条件进行过滤再返回结果. IQueryable: 从服务器处进行过滤,直接返回过滤后的结果.
- Python爬取 斗图表情,让你成为斗图大佬
话不多说,上结果(只爬了10页内容) 上代码:(可直接运行) 用到Xpath #encoding:utf-8 # __author__ = 'donghao' # __time__ = 2018/ ...
- vs 2017 IIS EXPRESS 增加局域网访问
在VS调试站点,默认使用IISExpress,locall+端口,为了使用IP地址.多域名调试,找到 IISExpress下的applicationhost.config,在目标站点下增加类似行: & ...
- Shell的并发
#!/bin/bash ./step1.sh & >中文 i=$! ./step2.sh & >西王 j=$! wait #echo ${i} #echo ${j} ech ...