package test;
import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 并发库中的BlockingQueue是一个比较好玩的类,顾名思义,就是阻塞队列。该类主要提供了两个方法put()和take(),前者将一个对象放到队列中,
* 如果队列已经满了,就等待直到有空闲节点;后者从head取一个对象,如果没有对象,就等待直到有可取的对象。
*
* 下面的例子比较简单,一个读线程,用于将要处理的文件对象添加到阻塞队列中,另外四个写线程用于取出文件对象,为了模拟写操作耗时长的特点,
* 特让线程睡眠一段随机长度的时间
* 。另外,该Demo也使用到了线程池和原子整型(AtomicInteger),AtomicInteger可以在并发情况下达到原子化更新
* ,避免使用了synchronized
* ,而且性能非常高。由于阻塞队列的put和take操作会阻塞,为了使线程退出,特在队列中添加了一个“标识”,算法中也叫“哨兵
* ”,当发现这个哨兵后,写线程就退出。 当然线程池也要显式退出了。
*
* @author lhj
*
*/
public class TestBlockingQueue {
static long randomTime() {
return (long) (Math.random() * 1000);
}
public static void main(String[] args) {
//能容纳100个文件
final BlockingQueue queue = new LinkedBlockingQueue(100);
//线程池
final ExecutorService exec = Executors.newFixedThreadPool(5);
final File root = new File("E://nio_framework-0.9.5_all");
//完成标志
final File exitFile = new File("");
//读个数
final AtomicInteger rc = new AtomicInteger();
//写个数
final AtomicInteger wc = new AtomicInteger();
//读线程
Runnable read = new Runnable() {
public void run() {
scanFile(root);
scanFile(exitFile);
}
public void scanFile(File file) {
if (file.isDirectory()) {
File[] files = file.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.isDirectory()
|| pathname.getPath().endsWith(".java");
}
});
for (File one : files) {
scanFile(one);
}
} else {
try {
int index = rc.incrementAndGet();
System.out.println("Read0: " + index + " "
+ file.getPath());
queue.put(file);
} catch (InterruptedException e) {
}
}
}
};
exec.submit(read);
//四个写线程
for (int index = 0; index < 4; index++) {
// write thread
final int NO = index;
Runnable write = new Runnable() {
String threadName = "Write" + NO;
public void run() {
while (true) {
try {
Thread.sleep(randomTime());
int index = wc.incrementAndGet();
File file = (File) queue.take();
//队列已经无对象
if (file == exitFile) {
// 再次添加”标志”,以让其他线程正常退出
queue.put(exitFile);
break;
}
System.out.println(threadName + ": " + index + " "
+ file.getPath());
} catch (InterruptedException e) {
}
}
}
};
exec.submit(write);
}
exec.shutdown();
}
}
分享到:
相关推荐
线程----BlockingQueue 的介绍说明
在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利。本文详细介绍了BlockingQueue...
BlockingQueue java 的工具类,初次要用于消费者,生产者的同步问题。
简单实现BlockingQueue,BlockingQueue源码详解
类似java BlockingQueue,C++写的,支持Windows与Linux。
定义全局线程池,将用户的请求放入自定义队列中,排队等候线程调用,等待超时则自动取消该任务,实现超时可取消的异步任务
这个demo主要讲解了BlockingQueue的使用希望可以帮户需要的同学.
14-阻塞队列BlockingQueue实战及其原理分析二.pdf
BlockingQueue是一种特殊的Queue,若BlockingQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态直到BlocingkQueue进了新货才会被唤醒,下面是用BlockingQueue来实现Producer和Consumer的例子
10、阻塞队列BlockingQueue实战及其原理分析_
在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利。本文简要介绍下BlockingQueue...
java中线程队列BlockingQueue的用法
主要介绍了Java多线程Queue、BlockingQueue和使用BlockingQueue实现生产消费者模型方法解析,涉及queue,BlockingQueue等有关内容,具有一定参考价值,需要的朋友可以参考。
BlockingQueue支持两个附加操作的Queue:1)当Queue为空时,获取元素线程被阻塞直到Queue变为非空;2)当Queue满时,添加元素线程被阻塞直到Queue不满。BlockingQueue不允许元素为null,如果入队一个null元素,会抛...
本篇文章小编为大家介绍,基于java中BlockingQueue的使用介绍。需要的朋友参考下
Java-concurrent-collections-concurrenthashmap-blockingqueue.pdf
6.6 阻塞队列BlockingQueue 实战及其原 理分析一副本.mp4
主要介绍了java 中 阻塞队列BlockingQueue详解及实例的相关资料,需要的朋友可以参考下
6.7 阻塞队列BlockingQueue 实战及其原 理分析二副本.mp4
6.6 阻塞队列BlockingQueue 实战及其原 理分析一副本副本.mp4