With Arrayblockingqueue, it is easy to implement both producer and consumer, and all consumer threads share resources arrayblockingqueue objects for thread safety. The producer thread searches the current directory and subdirectories and adds the corresponding file object to the queue , the consumer thread queries the keyword for each file object, and if it checks to the head, it stops the query.
ImportJava.io.File;Importjava.io.FileNotFoundException;ImportJava.util.Scanner;ImportJava.util.concurrent.ArrayBlockingQueue;ImportJava.util.concurrent.BlockingQueue;/*** Created by Administrator on 2016/6/30.*/ Public classBlockingqueuetest { Public Static voidMain (string[] args) {Scanner in=NewScanner (system.in); System.out.print ("Enter Base directory:"); String Directory=In.nextline (); System.out.println ("Enter key world."); String Keyworld=In.nextline (); Final intfile_queue_size=10;//volume of the queue Final intsearch_threads=100;//Number of consumer threads (queries with high concurrency)Blockingqueue<file>queue=NewArrayblockingqueue<>(file_queue_size); Fileenumerationtask Enumerator=NewFileenumerationtask (Queue,NewFile (directory));//Producer Threads NewThread (Enumerator). Start (); for(inti=1;i<search_threads;i++) { NewThread (NewSearchtask (Queue,keyworld)). Start ();//Turn on consumer threading } }}classFileenumerationtaskImplementsrunnable{ Public StaticFile dummy=NewFile ("");//to define a tag for the head of a queue PrivateBlockingqueue<file>queue; PrivateFile startingdirectory; PublicFileenumerationtask (blockingqueue<file>queue, File startingdirectory) { This. Queue =queue; This. Startingdirectory =startingdirectory; } @Override Public voidrun () {Try{Enumerate (startingdirectory); Queue.put (DUMMY); //put tags at the end of the queue}Catch(interruptedexception e) {e.printstacktrace (); } } Private voidEnumerate (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 (); } } } }}classSearchtaskImplementsRunnable {PrivateBlockingqueue<file>queue; PrivateString Keyworld; PublicSearchtask (blockingqueue<file>queue, String Keyworld) { This. Queue =queue; This. Keyworld =Keyworld; } @Override Public voidrun () {BooleanDone=false; while(!Done ) { Try{File File=queue.take ();//thread-safe operation, getting the file object if(file==fileenumerationtask.dummy) {queue.put (file); Done=true;//queue to head, no longer queried } Elsesearch (file); } Catch(interruptedexception e) {e.printstacktrace (); } } } Private voidSearch (file file) {Try { Try(Scanner in=NewScanner (file)) { intLinenumber=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 (); } }}
A multi-threaded and producer consumer model is used to search for the contents of files in a directory and all subdirectories, and prints the rows containing the specified keywords.