- 浏览: 83138 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
honghu:
朋友能把你的demo分享下吗?谢谢,honghu616@gma ...
最近做的Web流程设计器雏形,支持BPMN2.0 -
dyllove98:
Here is a workaround. It uses i ...
MappedByteBuffer 之文件删除问题 -
hahalzb:
thank you
JPA 概述及下载 -
geek87:
我的安装成功了。。呵呵
尝试使用Visual Editor 1.4 -
geek87:
谢谢了,我在试试安装
尝试使用Visual Editor 1.4
项目中需要用到多线程处理,线程的任务最好是动态的负载均衡,自然想到用阻塞队列。再次学习:
==============================================================================
Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法了,而不能直接访问LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。BlockingQueue 继承了Queue接口。
队列是一种数据结构.它有两个基本操作:在队列尾部加人一个元素,和从队列头部移除一个元素就是说,队列以一种先进先出的方式管理数据,如果你试图向一个已经满了的阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元索,将导致线程阻塞.在多线程进行合作时,阻塞队列是很有用的工具。工作者线程可以定期地把中间结果存到阻塞队列中而其他工作者线线程把中间结果取出并在将来修改它们。队列会自动平衡负载。如果第一个线程集运行得比第二个慢,则第二个线程集在等待结果时就会阻塞。如果第一个线程集运行得快,那么它将等待第二个线程集赶上来。下表显示了jdk1.5中的阻塞队列的操作:
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列满,则阻塞
take 移除并返回队列头部的元素 如果队列为空,则阻塞
remove、element、offer 、poll、peek 其实是属于Queue接口。
阻塞队列的操作可以根据它们的响应方式分为以下三类:aad、removee和element操作在你试图为一个已满的队列增加元素或从空队列取得元素时抛出异常。当然,在多线程程序中,队列在任何时间都可能变成满的或空的,所以你可能想使用offer、poll、peek方法。这些方法在无法完成任务时只是给出一个出错示而不会抛出异常。
注意:poll和peek方法出错进返回null。因此,向队列中插入null值是不合法的。
还有带超时的offer和poll方法变种,例如,下面的调用:
boolean success = q.offer(x,100,TimeUnit.MILLISECONDS);
尝试在100毫秒内向队列尾部插入一个元素。如果成功,立即返回true;否则,当到达超时进,返回false。同样地,调用:
Object head = q.poll(100, TimeUnit.MILLISECONDS);
如果在100毫秒内成功地移除了队列头元素,则立即返回头元素;否则在到达超时时,返回null。
最后,我们有阻塞操作put和take。put方法在队列满时阻塞,take方法在队列空时阻塞。
java.ulil.concurrent包提供了阻塞队列的4个变种。默认情况下,LinkedBlockingQueue的容量是没有上限的(说的不准确,在不指定时容量为Integer.MAX_VALUE,不要然的话在put时怎么会受阻呢),但是也可以选择指定其最大容量,它是基于链表的队列,此队列按 FIFO(先进先出)排序元素。
ArrayBlockingQueue在构造时需要指定容量,并可以选择是否需要公平性,如果公平参数被设置true,等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来达到这种公平性的:即等待时间最长的线程会先操作)。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队列,此队列按 FIFO(先进先出)原则对元素进行排序。
PriorityBlockingQueue是一个带优先级的队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对PriorityQueue的再次包装,是基于堆数据结构的,而PriorityQueue是没有容量限制的,与ArrayList一样,所以在优先阻塞队列上put时是不会受阻的。虽然此队列逻辑上是无界的,但是由于资源被耗尽,所以试图执行添加操作可能会导致 OutOfMemoryError),但是如果队列为空,那么取元素的操作take就会阻塞,所以它的检索操作take是受阻的。另外,往入该队列中的元素要具有比较能力。
最后,DelayQueue(基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满,poll就以移除这个元素了。此队列不允许使用 null 元素。 下面是延迟接口:
放入DelayQueue的元素还将要实现compareTo方法,DelayQueue使用这个来为元素排序。
下面的实例展示了如何使用阻塞队列来控制线程集。程序在一个目录及它的所有子目录下搜索所有文件,打印出包含指定关键字的文件列表。从下面实例可以看出,使用阻塞队列两个显著的好处就是:多线程操作共同的队列时不需要额外的同步,另外就是队列会自动平衡负载,即那边(生产与消费两边)处理快了就会被阻塞掉,从而减少两边的处理速度差距。下面是具体实现:
- public class BlockingQueueTest {
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- System.out.print("Enter base directory (e.g. /usr/local/jdk5.0/src): ");
- String directory = in.nextLine();
- System.out.print("Enter keyword (e.g. volatile): ");
- String keyword = in.nextLine();
- final int FILE_QUEUE_SIZE = 10;// 阻塞队列大小
- final int SEARCH_THREADS = 100;// 关键字搜索线程个数
- // 基于ArrayBlockingQueue的阻塞队列
- BlockingQueue<File> queue = new ArrayBlockingQueue<File>(
- FILE_QUEUE_SIZE);
- //只启动一个线程来搜索目录
- FileEnumerationTask enumerator = new FileEnumerationTask(queue,
- new File(directory));
- new Thread(enumerator).start();
- //启动100个线程用来在文件中搜索指定的关键字
- for (int i = 1; i <= SEARCH_THREADS; i++)
- new Thread(new SearchTask(queue, keyword)).start();
- }
- }
- class FileEnumerationTask implements Runnable {
- //哑元文件对象,放在阻塞队列最后,用来标示文件已被遍历完
- public static File DUMMY = new File("");
- private BlockingQueue<File> queue;
- private File startingDirectory;
- public FileEnumerationTask(BlockingQueue<File> queue, File startingDirectory) {
- this.queue = queue;
- this.startingDirectory = startingDirectory;
- }
- public void run() {
- try {
- enumerate(startingDirectory);
- queue.put(DUMMY);//执行到这里说明指定的目录下文件已被遍历完
- } catch (InterruptedException e) {
- }
- }
- // 将指定目录下的所有文件以File对象的形式放入阻塞队列中
- public void enumerate(File directory) throws InterruptedException {
- File[] files = directory.listFiles();
- for (File file : files) {
- if (file.isDirectory())
- enumerate(file);
- else
- //将元素放入队尾,如果队列满,则阻塞
- queue.put(file);
- }
- }
- }
- class SearchTask implements Runnable {
- private BlockingQueue<File> queue;
- private String keyword;
- public SearchTask(BlockingQueue<File> queue, String keyword) {
- this.queue = queue;
- this.keyword = keyword;
- }
- public void run() {
- try {
- boolean done = false;
- while (!done) {
- //取出队首元素,如果队列为空,则阻塞
- File file = queue.take();
- if (file == FileEnumerationTask.DUMMY) {
- //取出来后重新放入,好让其他线程读到它时也很快的结束
- queue.put(file);
- done = true;
- } else
- search(file);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- }
- }
- public void search(File file) throws IOException {
- Scanner in = new Scanner(new FileInputStream(file));
- int lineNumber = 0;
- while (in.hasNextLine()) {
- lineNumber++;
- String line = in.nextLine();
- if (line.contains(keyword))
- System.out.printf("%s:%d:%s%n", file.getPath(), lineNumber,
- line);
- }
- in.close();
- }
- }
==============================================================================
以上内容转载自:http://jiangzhengjun.iteye.com/blog/683593
发表评论
-
Java并发的四种风味
2015-08-07 09:21 472刚看到这篇文章,讨论了Java应用中并行处理的多种方法,其中 ... -
使用Ant构建Maven3项目【更新】
2013-04-03 00:40 1439之前的转的帖子经过验证发现还是有点问题的,所以打算重写一遍 ... -
婚礼用--宾客席位搜索器
2013-01-04 13:21 951前阵子事情多,又要准备结婚,所以博客好久没更新了。 2 ... -
Java 过滤文件的BOM头
2012-09-06 15:22 1336最近项目碰到一个小问题,配置文件如果用记事本改过,会因为解析错 ... -
nexus 初试笔记
2012-06-27 22:01 1205今天花了点时间研究了下Nexus,做个小笔记。 1.别 ... -
Vaadin 学习笔记
2012-03-22 22:50 0话说最近一个小项目,我实在是难以忍受不给力的美工MM,也受够了 ... -
开始试试Vaadin
2012-03-16 22:57 1336最近发现了一个比较有意思的Web Ria框架:Vaadin。官 ... -
Nutz中支持SLF4J
2011-11-15 14:08 2390Nutz是个不错的轻量级框架,小巧易用,不了解到同学可以 ... -
抛弃log4j改用logback
2011-11-04 14:09 8099公司的新平台最近日志总出问题: - 满容量后不自动备份,并且 ... -
JAVA 7 新特性
2011-08-02 17:25 1699Java 7 正式版已经发布,来看看新特性。(转载自OSC ... -
[多线程] 等待任务线程结束
2011-06-17 12:01 2392使用多线程容易碰到这样的问题,主线程需要等待各个任务线程完成后 ... -
[转] DbUnit 入门
2011-05-19 10:35 893什么是dbunit以及为什 ... -
log4j 日志文件的相对路径
2011-03-31 20:36 1040日志文件生成在工程目录下经常可以省去很多麻烦。 网上参 ... -
有顺序的Properties
2011-03-21 18:03 1779大家可能碰到过这样的问题,用properties文件保存配置信 ... -
Quartz 时间表达式
2011-03-15 17:55 1297最近用了下大名鼎鼎的quartz,基本能满足调度需求的变化了。 ... -
使用JXL(JExcelAPI)操作Excel
2011-02-28 15:27 1297原文链接:http://www.cnblogs.com/ray ... -
equinox web开发依赖包(jetty)
2010-11-06 19:07 1477今天尝试了下基于equinox的web开发,需要加入如下依赖包 ... -
Java游戏开发中应始终坚持的10项基本原则
2010-08-07 09:24 1221关于文章中涉及的两个杜撰概念:一、绘图器:众所周知,Ja ... -
Java游戏开发中怎样才能获得更快的FPS
2010-08-07 09:12 55众所周知,Java应用的 ... -
JPA 2.0 新特性
2010-06-28 15:04 918http://en.wikibooks.org/wiki/Ja ...
相关推荐
java学习(基于Java阻塞队列的搜索实例).pdf
java阻塞队列实现原理及实例解析.docx
java中,常用的阻塞式队列Demo。包含:ArrayBlockingQueue、LinkedQueue、PriorityBlockingQueue
消息分发框架,基于java阻塞队列实现,生产者消费者模型 可用于任务分发,服务器消息消息,以及网络IO 性能优化,多线程
主要介绍了java阻塞队列实现原理及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
实现java模拟阻塞队列的例子,该代码包括,阻塞队列实现生产者,消费者。和模拟阻塞队列实现生产者及消费者模式,帮助你更好的理解java多线程
主要介绍了详解Java阻塞队列(BlockingQueue)的实现原理,阻塞队列是Java util.concurrent包下重要的数据结构,有兴趣的可以了解一下
主要介绍了剖析Java中阻塞队列的实现原理及应用场景,这里也对阻塞和非阻塞队列的不同之处进行了对比,需要的朋友可以参考下
主要介绍了Java阻塞队列四组API介绍,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Java实现简单的阻塞队列2种方式,1使用wait(),notify();2使用countdownlatch实现
主要介绍了Java 阻塞队列详解及简单使用的相关资料,需要的朋友可以参考下
主要介绍了java 中 阻塞队列BlockingQueue详解及实例的相关资料,需要的朋友可以参考下
我们来讨论另外一类容器:阻塞队列。 在前面我们接触的队列都是非阻塞队列,比如PriorityQueue、LinkedList(LinkedList是双向链表,它实现了Dequeue接口)。 使用非阻塞队列的时候有一个很大问题是:它不会对...
java阻塞队列(Blocking Queue)是一个支持两个附加操作的队列.txt
先看看 BlockingQueue 接口的文档说明: 1、add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会抛出 IllegalStateException 异常;... 6、take:删除队列头部元素,如果队列为空,一直阻塞到队列有
并发-线程池和阻塞队列 并发-线程池和阻塞队列 并发-线程池和阻塞队列
主要介绍了Java中的阻塞队列详细介绍的相关资料,需要的朋友可以参考下
阻塞队列实现生产者消费者模式Java开发Java经验技巧共4页.pdf.zip
运行,登录时,请用两个浏览器登录,应为有不同session,这是跟据session来判断用户的