多线程原理-II 阻塞队列

来源:互联网 发布:python httperror代码 编辑:程序博客网 时间:2024/05/03 10:40

java线程是并发程序设计中的底层模块,而使用专家封装的线程控制工具则会更方便安全一点。阻塞队列的特点就是一个队列,先进先出的策略。线程之间协同工作的实例(引用:Java核心技术卷I 示例代码)

需求:列出指定目录下所有文件中包含指定关键词的行。
实现原理:阻塞队列
阻塞队列的机制:

这里写图片描述

线程FileEnumeration是前置线程,SearchTask是后置线程。前置线程不断向队列中添加,如果队列已满,就阻塞,等待其中一个后置线程完成,假如说,所有后置线程都在解析文件,而此时前置线程已经填满了队列。那么前置线程此时会阻塞。(put方法,在队列满时,会产生阻塞),等待一个后置线程完成腾出空间。

实例代码(unchecked):

public calss BlockingQueueTest{       public static void main(String [] args){               Scanner in=new Scanner(System.in);               System.out.println("Enter base directory:");               String directory=in.nextLIne();               System.out.print("Enter keyworld");               String keyword=in.nextLine();              final int File_Queue_Size=10;              final int Search_Threads=100;              BlockingQueue<File> queue=new ArrayBlockingQueue<File>(File_Queue_Size);              //阻塞队列创建             FileEnumberationTask enumerator=new FileEnumertionTask(queue,new File(directory));             new Thread(enumerator).start();             for(int i=1;i<=Search_Threads;i++){                   new Thread(new SearchTask(queue,keyword)).start();             }      }}//循环找出当前搜索目录下的所有文件class FileEnumerationTask implements Runnable{          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){               }          }         public void enumerate(File directory)throws InterruptedException{                File[] files=directory.listFiles();                for(File file: files){                      if(file.isDirectory())enumerate(file);                      else queue.put(file);                }        }      public static File DUMMY=new File("");      private BlockingQueue<File> queue;      private File startingDirectory;}     class SearchTask implements Runnable{             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){                           e.printStackTrace();                     }             }            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.println("%s:%d:%s%n",file.getPath(),lineNumber,line);                    }                in.close();             }            private BlockingQueue<File> queue;            private String keyword;  }