基于線程池的匹配文件數(shù)量計算
構(gòu)建一個新的線程的代價還是有些高的,因為它涉及與操作系統(tǒng)的交互。如果你的程序創(chuàng)建了大量生存期很短的線程,那就應該使用線程池。一個線程池包含大量準備運行的空閑線程。你將一個Runnable對象給線程池,線程池中的一個線程就會調(diào)用run方法。當run方法退出時,線程不會死亡,而是繼續(xù)在池中準備為下一個請求提供服務。
執(zhí)行器(Executor)類有大量用來構(gòu)建線程池的靜態(tài)工廠方法,下表給出了一個總結(jié)。
方法 | 描述 |
newCachedThreadPool | 在需要時創(chuàng)建新線程:空閑線程會被保留60秒 |
newFixedThreadPool | 池包含固定數(shù)量的線程;空閑線程會一直被保留 |
newSingleThreadExecutor | 只有一個線程的“池”,這個線程順序執(zhí)行每一個遞交上來的任務 |
newScheduledThreadPool | 為預定執(zhí)行而構(gòu)建的固定線程池 |
newSingleThreadScheduledExecutor | 為預定執(zhí)行而構(gòu)建的單線程“池” |
newCachedThreadPool、newFixedThreadPool和newSingleThreadExecutor這三個方法返回ThreadPoolExecutor類(這個類實現(xiàn)了ExecutorService接口)對象。
向線程池提交任務的方法為:將一個實現(xiàn)Runnable或Callable接口的對象提交給ExecutorService:
- Future<?> submit(Runable task)
- Future<T> submit(Runable task, T result)
- Future<t> submit(Callable<T> task)
線程池會在適當?shù)臅r候盡早執(zhí)行提交的任務,調(diào)用submit時會返回一個Future對象,用以查詢該任務的狀態(tài),或者取消該任務。
***個submit方法提交一個Runable對象返回一個Future<?>,可使用該對象調(diào)用isDone、cancel、或者isCancelled來查詢?nèi)蝿諣顟B(tài)。但是此Future對象的get方法在任務完成的時候知識簡單的返回null;
第二個版本的submit方法同樣提交一個Runable對象,并且返回Future的get方法在任務完成的時候返回傳入的result對象;
第三個submit方法提交一個Callable對象,并且返回的Future對象將在計算結(jié)構(gòu)、準備好的時候得到它。
當想要注銷一個線程池,可調(diào)用shutdown方法,該方法啟動該線程池的關閉序列。此時線程池并不是馬上就壯烈犧牲了線程也沒了,而是等待所以任務都完成以后,線程池中的線程才會死亡,被關閉的執(zhí)行器不再接受新任務。也可以調(diào)用shutdownNow,此時線程池會取消正在排隊等待處理的任務并且試圖中斷正在執(zhí)行的線程。
下面總結(jié)了在使用連接池時應該做的事:
- 調(diào)用Executor類中靜態(tài)的newCachedThreadPool或newFixedThreadPool方法。
- 調(diào)用submit來提交一個Runnable或Callable對象。
- 如果希望能夠取消任務或如果提交了一個Callable對象,那就保存好返回的Future對象。
- 當不想再提交任何任務時調(diào)用shutdown。
除了常規(guī)的計算匹配文件數(shù)量外,這個程序打印出執(zhí)行過程中池中的***線程數(shù)量。但從ExecutorService接口不能得到這個信息。因此,我們必須將pool對象轉(zhuǎn)型成一個ThreadPoolExecutor類對象。
- import java.io.*;
- import java.util.*;
- import java.util.concurrent.*;
- public class ThreadPoolTest
- {
- public static void main(String[] args) throws Exception
- {
- Scanner in = new Scanner(System.in);
- System.out.print("Enter base directory (e.g. /usr/local/jdk5.0/src): ");
- String directory = in.nextLine();
- System.out.print("Enter keyword (e.g. volatile): ");
- 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() + " matching files.");
- }
- catch (ExecutionException e)
- {
- e.printStackTrace();
- }
- catch (InterruptedException e)
- {
- }
- pool.shutdown();
- int largestPoolSize = ((ThreadPoolExecutor) pool).getLargestPoolSize();
- System.out.println("largest pool size=" + largestPoolSize);
- }
- }
- /**
- * This task counts the files in a directory and its subdirectories that contain a given keyword.
- */
- class MatchCounter implements Callable<Integer>
- {
- /**
- * Constructs a MatchCounter.
- * @param directory the directory in which to start the search
- * @param keyword the keyword to look for
- * @param pool the thread pool for submitting subtasks
- */
- public MatchCounter(File directory, String keyword, ExecutorService pool)
- {
- this.directory = directory;
- this.keyword = keyword;
- this.pool = pool;
- }
- public Integer call()
- {
- count = 0;
- try
- {
- File[] files = directory.listFiles();
- ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>();
- for (File file : files)
- if (file.isDirectory())
- {
- MatchCounter counter = new MatchCounter(file, keyword, pool);
- Future<Integer> result = pool.submit(counter);
- results.add(result);
- }
- else
- {
- if (search(file)) count++;
- }
- for (Future<Integer> result : results)
- try
- {
- 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
- {
- Scanner in = new Scanner(new FileInputStream(file));
- boolean found = false;
- while (!found && in.hasNextLine())
- {
- String line = in.nextLine();
- if (line.contains(keyword)) found = true;
- }
- in.close();
- return found;
- }
- catch (IOException e)
- {
- return false;
- }
- }
- private File directory;
- private String keyword;
- private ExecutorService pool;
- private int count;
- }
原文鏈接:http://www.cnblogs.com/XL-Liang/archive/2012/06/13/2548327.html