package thread.bolckqueue; import java.io.File; import java.util.Scanner; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class TestOne { private static final int FILE_QUENE_SIZE = 1; private static final int SEARCH_THREADS = 100; private static final File DUMMY= new File(""); private static final BlockingQueue<File> queue = new ArrayBlockingQueue<>(FILE_QUENE_SIZE); public static void main(String[] args) { // TODO Auto-generated method stub //阻塞队列 //使用队列可以安全从一个线程向另一个线程传递数据,操作的是队列而不是对象 //队列已满,向其中添加线程,获取移除空队列的时候会阻塞。 //队列会平衡负载,第一个线程集运行的比第二个慢,第二个线程集在等待结果时会堵塞,或者第一个线程集运行的比较快,会等待第二个线程集赶上来 /** * * 阻塞队列方法分为以下 3类, 这取决于当队列满或空时它们的响应方式。 * 如果将队列当 作线程管理工具来使用, 将要用到 put 和 take 方法。 * 当试图向满的队列中添加或从空的队列 中移出元素时,add、 remove 和 element 操作抛出异常。 * 当然,在一个多线程程序中, 队列会 在任何时候空或满, 因此,一定要使用 offer、poll 和 peek方法作为替代。 * 这些方法如果不能 完成任务,只是给出一个错误提示而不会抛出异常 * * * * put 添加一个元素,如果队列满则阻塞 * * take 移除并返回头元素 ,如果队列已满则会堵塞 * */ /** * 查找文件夹下的多个文件,打印包含keyword的文件 */ try (Scanner in = new Scanner(System.in)){ System.out.print("Enter base directory (e.g. /opt/jdk1.8.0/src):"); String directory = in.nextLine(); System.out.print("Enter keyword (e.g.volatile): "); String keyword = in.nextLine(); Runnable en = () ->{ try { enumerate(new File(directory)); queue.put(DUMMY); } catch (InterruptedException e) { e.printStackTrace(); } }; new Thread(en).start(); for (int i = 0; i < SEARCH_THREADS; i++) { Runnable searcher = () -> { try { boolean done = false; while (!done) { File file = queue.take(); if (file == DUMMY) { queue.put(file); done = true; }else { search(file, keyword); } } } catch (InterruptedException e) { e.printStackTrace(); } }; new Thread(searcher).start(); } } catch (Exception e) { e.printStackTrace(); } } public static void enumerate(File directory){ try { File[] files = directory.listFiles(); for (File file : files) { if (file.isDirectory()) { enumerate(file); } else { queue.put(file); } } } catch (InterruptedException e) { e.printStackTrace(); } } public static void search(File file ,String keyword){ 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%n",file.getPath(),lineNumber,line); } } } catch (Exception e) { e.printStackTrace(); } } }