码迷,mamicode.com
首页 > 编程语言 > 详细

Java多线程——阻塞队列

时间:2015-02-03 23:08:11      阅读:489      评论:0      收藏:0      [点我收藏+]

标签:多线程   java   thread   阻塞队列   

        现在,通过前几篇的总结,我们对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<File> queue;
    private final File                startingDirectory;

    public FileEnumerationTask(BlockingQueue<File> 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<File> queue;
    private final String              keyword;

    public SearchTask(BlockingQueue<File> 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<File> 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();
        }
    }
}

测试结果:
技术分享

Java多线程——阻塞队列

标签:多线程   java   thread   阻塞队列   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!