Java 多线程,线程池,

1. 创建线程池的方法之三:

    //对于每个任务,如果有空闲的线程可用,立即让他执行任务,
    //没有空闲的线程则创建一个线程。
    ExecutorService pool = Executors.newCachedThreadPool();
    //固定大小的线程池,任务数 > 空闲线程数,得不到服务的任务置于队列
    ExecutorService pool = Executors.newFixedThreadPool;
    //退化的大小为1的线程池,由一个线程逐个执行提交的任务。
    ExecutorService pool = Executors.newSingleThreadPool();

2. 把任务交给线程池:

    //返回的对象可以调用isDone(),cancel(),isCancelled
    Future<?> submit(Runnable task);
    //get() 返回指定的result对象
    Future<T> submit(Runnable task,T result);
    //返回的对象将在计算结果准备好的时候得到它。
    Future<T> submit(Callable<T> task);

3.用完一个线程池的时候,调用shutdown() 启动线程池的关闭序列。被关闭的执行器不再接受新的任务,当任务都结束后,线程池中的线程死亡。

4. 案例:给定一个目录,查找目录中文本文档内容包含指定关键字的文档的数量。

  条件:目录、关键字

  4.1 任务类(线程类)

   /** 线程任务:计算目录中所有包含给定关键字的文件的数量。*/
   class MatchCounter implements Callable<Integer>
   {
      private File directory;
      private String keyword;
      private ExecutorService pool;
      private int count;

      /**
       * Constructs a MatchCounter.
       * @param directory 给定的目录
       * @param keyword 关键字
       * @param pool 用来执行任务的线程池
       */
      public MatchCounter(File directory, String keyword, ExecutorService pool)
      {
         this.directory = directory;
         this.keyword = keyword;
         this.pool = pool;
      }

      @Override
      public Integer call()
      {
         count = 0;
         try
         {
            File[] files = directory.listFiles();
            //线程执行结果集合
            List<Future<Integer>> results = new ArrayList<>();

            for (File file : files)
               //遍历给定目录中的所有文件
               //如果是文件夹
               if (file.isDirectory())
               {
                  //递归
                  MatchCounter counter = new MatchCounter(file, keyword, pool);
                  Future<Integer> result = pool.submit(counter);
                  results.add(result);
               }
               //如果是文件,则调用search()方法 看是否包含关键字。
               else
               {
                  if (search(file)) count++;
               }

            for (Future<Integer> result : results)
               try
               {
                  int a = result.get();
                  count += result.get();
               }
               catch (ExecutionException e)
               {
                  e.printStackTrace();
               }
         }
         catch (InterruptedException e)
         {
         }
         return count;
      }

      /**
       * Searches a file for a given keyword.
       * @param file the file to search
       * @return true if the keyword is contained in the file
       */
      public boolean search(File file)
      {
         try
         {
            try (Scanner in = new Scanner(file, "UTF-8"))
            {
               boolean found = false;
               while (!found && in.hasNextLine())
               {
                  String line = in.nextLine();
                  if (line.contains(keyword)) found = true;
               }
               return found;
            }
         }
         catch (IOException e)
         {
            return false;
         }
      }
   }

  4.2 主程序

  

    public class ThreadPoolTest
   {
      public static void main(String[] args) throws Exception
      {
         try (Scanner in = new Scanner(System.in))
         {
            System.out.print("请输入要查找的目录:");
            String directory = in.nextLine();
            System.out.print("请输入要查找的关键字:");
            String keyword = in.nextLine();
      
            ExecutorService pool = Executors.newCachedThreadPool();
      
            MatchCounter counter = new MatchCounter(new File(directory), keyword, pool);
            Future<Integer> result = pool.submit(counter);
      
            try
            {
               System.out.println(result.get() + " 匹配的文件");
            }
            catch (ExecutionException e)
            {
               e.printStackTrace();
            }
            catch (InterruptedException e)
            {
            }
            pool.shutdown();
      
            int largestPoolSize = ((ThreadPoolExecutor) pool).getLargestPoolSize();
            System.out.println("线程池最大数量 =" + largestPoolSize);
         }
      }
   }

  4.3 运行结果:

  

 

posted @ 2019-08-08 14:47  lovleo  阅读(163)  评论(0编辑  收藏  举报