🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
使用一个生产者线程将一个目录下的所有文件放入阻塞队列中,使用100个消费者线程从阻塞队列中获取文件,并将文件中含有关键字的句子打印到控制台上。 ```java public class BlockingQueueTest { //队列初始容量 private static final int FILE_QUEUE_SIZE = 10; //100个消费者线程 private static final int SEARCH_THREADS = 100; //用于退出线程 private static final File DUMMY = new File(""); //阻塞队列ArrayBlockingQueue private static BlockingQueue<File> queue = new ArrayBlockingQueue<>(FILE_QUEUE_SIZE); /** * 递归枚举给定目录及其子目录中的所有文件,并把文件放入队列中 * * @param directory,开始递归的目录 * @throws InterruptedException */ public static void enumerate(File directory) throws InterruptedException { File[] files = directory.listFiles(); for (File file : files) { if (file.isDirectory()) enumerate(file); else queue.put(file); } } /** * 在文件中搜索给定的关键字并打印所有匹配的行 * * @param file,被搜索的文件 * @param keyword,需要匹配的关键字 * @throws IOException */ public static void search(File file, String keyword) throws IOException { try (Scanner in = new Scanner(file, "UTF-8")) { 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); } } } } public static void main(String[] args) { try (Scanner in = new Scanner(System.in)) { System.out.println("请输入一个目录: "); String directory = in.nextLine(); System.out.println("请输入一个关键字: "); String keyword = in.nextLine(); Runnable enumerator = () -> { try { enumerate(new File(directory)); queue.put(DUMMY); //存储一个null的元素,用来作为退出线程的条件 } catch (InterruptedException e) { } }; //启动生产者线程 new Thread(enumerator).start(); for (int i = 1; i <= SEARCH_THREADS; i++) { Runnable searcher = () -> { try { boolean done = false; while (!done) { File file = queue.take(); //这是消费者线程退出的条件,如果队列最后一个元素为null,则退出线程 if (file == DUMMY) { queue.put(file); done = true; } else { search(file, keyword); } } } catch (IOException e) { } catch (InterruptedException e) { } }; //启动消费者线程 new Thread(searcher).start(); } } } } ```