熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

基於線程池的匹配文件數量計算

2022-06-13   來源: Java高級技術 
    構建一個新的線程的代價還是有些高的因為它涉及與操作系統的交互如果你的程序創建了大量生存期很短的線程那就應該使用線程池一個線程池包含大量准備運行的空閒線程你將一個Runnable對象給線程池線程池中的一個線程就會調用run方法當run方法退出時線程不會死亡而是繼續在池中准備為下一個請求提供服務
   
    執行器(Executor)類有大量用來構建線程池的靜態工廠方法下表給出了一個總結
   
    newCachedThreadPoolnewFixedThreadPool和newSingleThreadExecutor這三個方法返回ThreadPoolExecutor類(這個類實現了ExecutorService接口)對象
   
    向線程池提交任務的方法為將一個實現Runnable或Callable接口的對象提交給ExecutorService:
   
    Future<?> submit(Runable task)
   
    Future<T> submit(Runable task T result)
   
    Future<t> submit(Callable<T> task)
   
    線程池會在適當的時候盡早執行提交的任務調用submit時會返回一個Future對象用以查詢該任務的狀態或者取消該任務
   
    第一個submit方法提交一個Runable對象返回一個Future<?>可使用該對象調用isDonecancel或者isCancelled來查詢任務狀態但是此Future對象的get方法在任務完成的時候知識簡單的返回null;
   
    第二個版本的submit方法同樣提交一個Runable對象並且返回Future的get方法在任務完成的時候返回傳入的result對象
   
    第三個submit方法提交一個Callable對象並且返回的Future對象將在計算結構准備好的時候得到它
   
    當想要注銷一個線程池可調用shutdown方法該方法啟動該線程池的關閉序列此時線程池並不是馬上就壯烈犧牲了線程也沒了而是等待所以任務都完成以後線程池中的線程才會死亡被關閉的執行器不再接受新任務也可以調用shutdownNow此時線程池會取消正在排隊等待處理的任務並且試圖中斷正在執行的線程
   
    下面總結了在使用連接池時應該做的事
   
    調用Executor類中靜態的newCachedThreadPool或newFixedThreadPool方法
   
    調用submit來提交一個Runnable或Callable對象
   
    如果希望能夠取消任務或如果提交了一個Callable對象那就保存好返回的Future對象
   
    當不想再提交任何任務時調用shutdown
   
    除了常規的計算匹配文件數量外這個程序打印出執行過程中池中的最大線程數量但從ExecutorService接口不能得到這個信息因此我們必須將pool對象轉型成一個ThreadPoolExecutor類對象
   
    import javaio*;
   
    import javautil*;
   
    import ncurrent*;
   
    public class ThreadPoolTest
   
    {
   
    public static void main(String[] args) throws Exception
   
    {
   
    Scanner in = new Scanner(Systemin)
   
    Systemoutprint(Enter base directory (eg /usr/local/jdk/src)
   
    String directory = innextLine()
   
    Systemoutprint(Enter keyword (eg volatile)
   
    String keyword = innextLine()
   
    ExecutorService pool = ExecutorsnewCachedThreadPool()
   
    MatchCounter counter = new MatchCounter(new File(directory) keyword pool)
   
    Future<Integer> result = poolsubmit(counter)
   
    try
   
    {
   
    Systemoutprintln(resultget() + matching files
   
    }
   
    catch (ExecutionException e)
   
    {
   
    eprintStackTrace()
   
    }
   
    catch (InterruptedException e)
   
    {
   
    }
   
    poolshutdown()
   
    int largestPoolSize = ((ThreadPoolExecutor) pool)getLargestPoolSize()
   
    Systemoutprintln(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)
   
    {
   
    thisdirectory = directory;
   
    thiskeyword = keyword;
   
    thispool = pool;
   
    }
   
    public Integer call()
   
    {
   
    count = ;
   
    try
   
    {
   
    File[] files = directorylistFiles()
   
    ArrayList<Future<Integer》 results = new ArrayList<Future<Integer》()
   
    for (File file : files)
   
    if (fileisDirectory())
   
    {
   
    MatchCounter counter = new MatchCounter(file keyword pool)
   
    Future<Integer> result = poolsubmit(counter)
   
    resultsadd(result)
   
    }
   
    else
   
    {
   
    if (search(file)) count++;
   
    }
   
    for (Future<Integer> result : results)
   
    try
   
    {
   
    count += resultget()
   
    }
   
    catch (ExecutionException e)
   
    {
   
    eprintStackTrace()
   
    }
   
    }
   
    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 && inhasNextLine())
   
    {
   
    String line = innextLine()
   
    if (ntains(keyword)) found = true;
   
    }
   
    inclose()
   
    return found;
   
    }
   
    catch (IOException e)
   
    {
   
    return false;
   
    }
   
    }
   
    private File directory;
   
    private String keyword;
   
    private ExecutorService pool;
   
    private int count;
   
    }


From:http://tw.wingwit.com/Article/program/Java/gj/201311/27555.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.