利用ArrayBlockingQueue可以方便的实现生产者和消费者,所有消费者线程共用资源ArrayBlockingQueue对象,从而实现线程安全.生产者线程搜索当前目录及子目录,并且将相应的File对象添加到队列中,消费者线程对每个File对象进行关键字的查询,如果查到头,即停止查询.
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** * Created by Administrator on 2016/6/30. */ public class BlockingQueueTest { public static void main(String[] args) { Scanner in=new Scanner(System.in); System.out.print("Enter base directory:"); String directory=in.nextLine(); System.out.println("Enter key world."); String keyworld=in.nextLine(); final int FILE_QUEUE_SIZE=10; //队列的容积 final int SEARCH_THREADS=100; //消费者线程数目,(进行高并发的查询) BlockingQueue<File>queue=new ArrayBlockingQueue<>(FILE_QUEUE_SIZE); FileEnumerationTask enumerator=new FileEnumerationTask(queue,new File(directory));//生产者线程 new Thread(enumerator).start(); for (int i=1;i<SEARCH_THREADS;i++) { new Thread(new SearchTask(queue,keyworld)).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; } @Override public void run() { try { enumerate(startingDirectory); queue.put(DUMMY); //在队列的最后放入标记 } catch (InterruptedException e) { e.printStackTrace(); } } private void enumerate(File startingDirectory) { File[] files=startingDirectory.listFiles(); for(File file:files) { if(file.isDirectory()) { enumerate(file); } else { try { queue.put(file); } catch (InterruptedException e) { e.printStackTrace(); } } } } } class SearchTask implements Runnable { private BlockingQueue<File> queue; private String keyworld; public SearchTask(BlockingQueue<File> queue, String keyworld) { this.queue = queue; this.keyworld = keyworld; } @Override public void run() { boolean done=false; while (!done) { try { File file=queue.take(); //线程安全的操作,取得File对象 if(file==FileEnumerationTask.DUMMY) { queue.put(file); done=true; //队列到头,不再查询 } else search(file); } catch (InterruptedException e) { e.printStackTrace(); } } } private void search(File file) { try { try(Scanner in=new Scanner(file)) { int lineNumber=0; while(in.hasNextLine()) { lineNumber++; String line=in.nextLine(); if(line.contains(keyworld)) { System.out.printf("%s:%d:%s:%n",file.getPath(),lineNumber,line); } } } } catch (FileNotFoundException e) { e.printStackTrace(); } } }