阻塞队列

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();
        }
    }
    

}
原文地址:https://www.cnblogs.com/lxh520/p/8480305.html