`

网上摘录的LinkedBlockingQueue和ArrayBlockingQueue使用例子

 
阅读更多
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
 
/**
 * 
 * 阻塞队列LinkedBlockingQueue和ArrayBlockingQueue的使用
 * 
 */
public class BlockingQueueTest {
 
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("Enter base directory (e.g. /tmp/work/): ");
        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;// 关键字搜索线程个数
 
        // BlockingQueue<File> queue = new
        // ArrayBlockingQueue<File>(FILE_QUEUE_SIZE);
        BlockingQueue<File> queue = new LinkedBlockingQueue<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();
    }
}

 

分享到:
评论

相关推荐

    java中LinkedBlockingQueue与ArrayBlockingQueue的异同

    Java中的`LinkedBlockingQueue`和`ArrayBlockingQueue`都是`java.util.concurrent`包下的线程安全队列,它们都实现了`BlockingQueue`接口,提供了一种高效、线程安全的数据同步方式。这两种队列在很多方面都有相似之...

    并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解

    ArrayBlockingQueue和LinkedBlockingQueue的主要区别在于存储元素的方式,ArrayBlockingQueue使用数组存储元素,而LinkedBlockingQueue使用链表存储元素。因此,ArrayBlockingQueue更适合固定大小的队列,而...

    LinkedBlockingQueue 和 ConcurrentLinkedQueue的区别.docx

    LinkedBlockingQueue和ConcurrentLinkedQueue是Java并发包中两个常用的线程安全队列,它们各有特点,适用于不同的场景。本文将深入探讨两者之间的差异以及如何根据需求选择合适的队列。 首先,LinkedBlockingQueue...

    详细分析Java并发集合LinkedBlockingQueue的用法

    同时,LinkedBlockingQueue也使用Condition实现条件变量,用于队列为空和队列已满的情况下阻塞等待。 四、 LinkedBlockingQueue的优点 LinkedBlockingQueue相比ArrayBlockingQueue,LinkedBlockingQueue的优点是...

    linkedblockingqueue

    2. 使用非空构造器:如果队列必须保持非空状态,可以使用`new LinkedBlockingQueue(1)`这样的构造器。 3. 避免死锁:确保多个`BlockingQueue`的操作顺序一致,防止死锁的发生。 4. 谨慎使用`peek()`:该方法不会...

    ArrayBlockingQueue源码分析.docx

    `ArrayBlockingQueue` 内部使用了两个等待条件变量 `notFull` 和 `notEmpty`,它们都是 `ReentrantLock` 的 `Condition` 对象。当队列满时,`put()` 操作会调用 `notFull.await()` 让当前线程等待,而 `take()` 或 ...

    java并发之ArrayBlockingQueue详细介绍

    ArrayBlockingQueue使用ReentrantLock和两个Condition来实现线程安全的操作。ReentrantLock是Java并发编程中常用的锁实现,它可以重入锁,允许同一个线程多次获得锁。两个Condition分别是notEmpty和notFull,用于...

    并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    下面通过一个具体的例子来说明如何使用 `LinkedBlockingQueue`: ```java import java.util.concurrent.*; public class BlockingQueueTest2 { // 定义一个篮子类 public class Basket { // 初始化篮子的容量...

    LinkedBlockingQueuejava.pdf

    相比于基于数组的`ArrayBlockingQueue`,`LinkedBlockingQueue`在大多数情况下具有更好的性能,因为插入和删除操作不需要数组的重新分配。 五、公平与非公平策略 `LinkedBlockingQueue`有两种策略:公平(FIFO)和...

    LinkedBlockingQueue + 单向链表基本结构

    《深入理解LinkedBlockingQueue与单向链表结构》 LinkedBlockingQueue是Java并发包`java.util.concurrent`中的一个先进先出(FIFO)队列,它基于链表结构实现,特别适用于高并发场景。该队列的主要特点是其内部数据...

    ArrayBlockingQueue源码解析-动力节点共

    ArrayBlockingQueue内部由一个数组`items`存储元素,使用两个指针`head`和`tail`分别表示队头和队尾。在并发环境下,为了保证线程安全,ArrayBlockingQueue采用了ReentrantLock(可重入锁)来实现同步,并且在某些...

    JDK容器学习之Queue:LinkedBlockingQueue

    与数组结构的`ArrayBlockingQueue`不同,`LinkedBlockingQueue`使用单向链表实现,这使得插入和删除操作的效率相对较高,因为它们只需要修改相邻节点的引用。链表的头节点`head`不包含有效数据,而尾节点`last`保存...

    并发容器的原理,7大并发容器详解、及使用场景

    它们分别基于链表、数组和优先级堆实现,其中 ArrayBlockingQueue 和 LinkedBlockingQueue 使用 ReentrantLock 和 Condition 实现线程安全,PriorityBlockingQueue 则是一个按优先级排序的队列。 在选择并发容器时...

    spring-blockingqueue:用Spring Boot阻止队列

    通常,我们会选择实现BlockingQueue的类,如ArrayBlockingQueue、LinkedBlockingQueue或PriorityBlockingQueue,根据实际需求选择合适的实现。 例如,我们可以创建一个配置类,如下所示: ```java @Configuration ...

    backport-util-concurrent

    4. **阻塞队列**:BlockingQueue接口及其实现类如LinkedBlockingQueue和ArrayBlockingQueue,是线程间通信的重要工具。它们允许线程在队列满时等待,空时阻塞,保证了数据的有序处理。 5. **CyclicBarrier和...

    元素唯一的LinkedBlockingQueue阻塞队列

    `LinkedBlockingQueue`的实现充分利用了Java的`java.util.concurrent`包,提供了线程安全的数据结构和操作。 在`LinkedBlockingQueue`中,元素唯一性是一个重要的概念。这意味着队列中的每个元素都是独一无二的,...

    java多线程并发编程例子

    `TestBlockingQueue.java`可能包含如何使用`ArrayBlockingQueue`、`LinkedBlockingQueue`等实现线程间的通信和数据交换的示例。 3. **CompletionService**:`CompletionService`提供了一种获取异步任务结果的机制,...

    java常用知识例子讲解

    Java的`BlockingQueue`接口提供了线程安全的数据结构,可以方便地实现这种模式,如`ArrayBlockingQueue`、`LinkedBlockingQueue`等。 再者,反射是Java提供的一种强大功能,允许程序在运行时动态访问和修改类的信息...

Global site tag (gtag.js) - Google Analytics