java多线程阻塞队列,Java多线程——阻塞队列

现在,通过前几篇的总结,我们对Java多线程已经有所了解了,但是它们都是一些Java并发程序设计基础的底层构建块。对于实际编程来说,我们应该尽可能的远离底层结构。使用那些由并发处理的专业人士实现的较高层次的结构要方便的多,安全的多。

阻塞队列

对于许多线程问题。可以通过使用一个或多个队列以优雅且安全的方式将其形式化。生产者线程向队列插入元素,消费者线程则取出他们。使用队列,可以安全地从一个线程向另一个线程传递数据。

阻塞队列的方法

方法

正常动作

特殊情况下动作

add

添加一个元素

如果队列满,则抛出IllegalStateException异常

element

返回队列的头元素

如果队列空,抛出NoSuchElementException异常

offer

添加一个元素并返回true

如果队列满,返回false

peek

返回队列的头元素

如果队列空,则返回null

poll

移出并返回队列的头元素

如果队列空,则返回null

put

添加一个元素

如果队列满,则阻塞

remove

移出并返回头元素

如果队列空,则抛出NoSuchElementException异常

take

移出并返回头元素

如果队列满,则阻塞

阻塞队列的使用

接下来我们使用使用阻塞队列来控制一组线程。程序在一个目录及它的所有子目录下搜索所有文件,打印出包含指定关键字的行。

生产者线程列举所有子目录下的文件并把它们放在一个阻塞队列中。同时启动大量的搜索线程,每个搜索线程从队列中取出一个文件,打开它,打印所有包含关键字的行,然后去取下一个文件。终止线程方面,在队列最后添加一个虚拟对象,当搜索线程取到这个对象时,将它放回并终止线程。

FileEnumerationTask线程类:(将目录里的文件加入到队列)

/**

* @author xzzhao

*/

public class FileEnumerationTask implements Runnable {

public static File DUMMY = new File("");

private final BlockingQueue queue;

private final File startingDirectory;

public FileEnumerationTask(BlockingQueue queue, File startingDirectory) {

super();

this.queue = queue;

this.startingDirectory = startingDirectory;

}

@Override

public void run() {

try {

enumerate(startingDirectory);

queue.put(DUMMY);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

public void enumerate(File directory) throws InterruptedException {

File[] files = directory.listFiles();

for (File file : files) {

if (file.isDirectory()) {

enumerate(directory);

} else {

queue.put(file);

}

}

}

}

SearchTask线程类:(根据关键字搜索行)

/**

* @author xzzhao

*/

public class SearchTask implements Runnable {

private final BlockingQueue queue;

private final String keyword;

public SearchTask(BlockingQueue queue, String keyword) {

super();

this.queue = queue;

this.keyword = keyword;

}

@Override

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) {

e.printStackTrace();

}

}

/**

* 根据关键字搜索

*

* @param file

* @throws FileNotFoundException

*/

public void search(File file) throws FileNotFoundException {

try (Scanner in = new Scanner(file)) {

int lineNumber = 0;

while (in.hasNextLine()) {

lineNumber++;

String line = in.nextLine();

if (line.contains(keyword)) {

System.out.println("路径:" + file.getPath() + " 行号:" + lineNumber + " 行:" + line);

}

}

}

}

}

BlockingQueueTest类:(测试)

/**

* @author xzzhao

*/

public class BlockingQueueTest {

public static void main(String[] args) {

final int FILE_QUEUE_SIZE = 10;

final int SERCH_THREADS = 100;

Scanner in = new Scanner(System.in);

System.out.println("请输入根目录 :");

String directory = in.nextLine();

System.out.println("请输入关键字 :");

String keyword = in.nextLine();

BlockingQueue queue = new ArrayBlockingQueue<>(FILE_QUEUE_SIZE);

FileEnumerationTask enumerator = new FileEnumerationTask(queue, new File(directory));

new Thread(enumerator).start();

for (int i = 0; i <= SERCH_THREADS; i++) {

new Thread(new SearchTask(queue, keyword)).start();

}

}

}

测试结果:

4296bfc7926aba7cc7cdcdc0a99d6ca1.png

原文:http://blog.csdn.net/qq710262350/article/details/43454027

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值