1. 创建线程池的方法之三:
1//对于每个任务,如果有空闲的线程可用,立即让他执行任务, 2 //没有空闲的线程则创建一个线程。 3 ExecutorService pool = Executors.newCachedThreadPool(); 4 //固定大小的线程池,任务数 > 空闲线程数,得不到服务的任务置于队列 5 ExecutorService pool = Executors.newFixedThreadPool; 6 //退化的大小为1的线程池,由一个线程逐个执行提交的任务。 7 ExecutorService pool = Executors.newSingleThreadPool();
2. 把任务交给线程池:
1//返回的对象可以调用isDone(),cancel(),isCancelled 2 Future<?> submit(Runnable task); 3 //get() 返回指定的result对象 4 Future<T> submit(Runnable task,T result); 5 //返回的对象将在计算结果准备好的时候得到它。 6 Future<T> submit(Callable<T> task);
3.用完一个线程池的时候,调用shutdown() 启动线程池的关闭序列。被关闭的执行器不再接受新的任务,当任务都结束后,线程池中的线程死亡。
4. 案例:给定一个目录,查找目录中文本文档内容包含指定关键字的文档的数量。
条件:目录、关键字
4.1 任务类(线程类)
1/** 线程任务:计算目录中所有包含给定关键字的文件的数量。*/ 2 class MatchCounter implements Callable<Integer> 3 { 4 private File directory; 5 private String keyword; 6 private ExecutorService pool; 7 private int count; 8 9 /** 10 * Constructs a MatchCounter. 11 * @param directory 给定的目录 12 * @param keyword 关键字 13 * @param pool 用来执行任务的线程池 14 */ 15 public MatchCounter(File directory, String keyword, ExecutorService pool) 16 { 17 this.directory = directory; 18 this.keyword = keyword; 19 this.pool = pool; 20 } 21 22 @Override 23 public Integer call() 24 { 25 count = 0; 26 try 27 { 28 File[] files = directory.listFiles(); 29 //线程执行结果集合 30 List<Future<Integer>> results = new ArrayList<>(); 31 32 for (File file : files) 33 //遍历给定目录中的所有文件 34 //如果是文件夹 35 if (file.isDirectory()) 36 { 37 //递归 38 MatchCounter counter = new MatchCounter(file, keyword, pool); 39 Future<Integer> result = pool.submit(counter); 40 results.add(result); 41 } 42 //如果是文件,则调用search()方法 看是否包含关键字。 43 else 44 { 45 if (search(file)) count++; 46 } 47 48 for (Future<Integer> result : results) 49 try 50 { 51 int a = result.get(); 52 count += result.get(); 53 } 54 catch (ExecutionException e) 55 { 56 e.printStackTrace(); 57 } 58 } 59 catch (InterruptedException e) 60 { 61 } 62 return count; 63 } 64 65 /** 66 * Searches a file for a given keyword. 67 * @param file the file to search 68 * @return true if the keyword is contained in the file 69 */ 70 public boolean search(File file) 71 { 72 try 73 { 74 try (Scanner in = new Scanner(file, "UTF-8")) 75 { 76 boolean found = false; 77 while (!found && in.hasNextLine()) 78 { 79 String line = in.nextLine(); 80 if (line.contains(keyword)) found = true; 81 } 82 return found; 83 } 84 } 85 catch (IOException e) 86 { 87 return false; 88 } 89 } 90 }
4.2 主程序
1public class ThreadPoolTest 2 { 3 public static void main(String[] args) throws Exception 4 { 5 try (Scanner in = new Scanner(System.in)) 6 { 7 System.out.print("请输入要查找的目录:"); 8 String directory = in.nextLine(); 9 System.out.print("请输入要查找的关键字:"); 10 String keyword = in.nextLine(); 11 12 ExecutorService pool = Executors.newCachedThreadPool(); 13 14 MatchCounter counter = new MatchCounter(new File(directory), keyword, pool); 15 Future<Integer> result = pool.submit(counter); 16 17 try 18 { 19 System.out.println(result.get() + " 匹配的文件"); 20 } 21 catch (ExecutionException e) 22 { 23 e.printStackTrace(); 24 } 25 catch (InterruptedException e) 26 { 27 } 28 pool.shutdown(); 29 30 int largestPoolSize = ((ThreadPoolExecutor) pool).getLargestPoolSize(); 31 System.out.println("线程池最大数量 =" + largestPoolSize); 32 } 33 } 34 }
4.3 运行结果:
