qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

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

           除了常規的計算匹配文件數量外,這個程序打印出執行過程中池中的最大線程數量。但從ExecutorService接口不能得到這個信息。因此,我們必須將pool對象轉型成一個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;
          }

          構建一個新的線程的代價還是有些高的,因為它涉及與操作系統的交互。如果你的程序創建了大量生存期很短的線程,那就應該使用線程池。一個線程池包含大量準備運行的空閑線程。你將一個Runnable對象給線程池,線程池中的一個線程就會調用run方法。當run方法退出時,線程不會死亡,而是繼續在池中準備為下一個請求提供服務。

           

            執行器(Executor)類有大量用來構建線程池的靜態工廠方法,下表給出了一個總結。

            newCachedThreadPool、newFixedThreadPool和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<?>,可使用該對象調用isDone、cancel、或者isCancelled來查詢任務狀態。但是此Future對象的get方法在任務完成的時候知識簡單的返回null

            第二個版本的submit方法同樣提交一個Runable對象,并且返回Future的get方法在任務完成的時候返回傳入的result對象

            第三個submit方法提交一個Callable對象,并且返回的Future對象將在計算結構、準備好的時候得到它。

            當想要注銷一個線程池,可調用shutdown方法,該方法啟動該線程池的關閉序列。此時線程池并不是馬上就壯烈犧牲了線程也沒了,而是等待所以任務都完成以后,線程池中的線程才會死亡,被關閉的執行器不再接受新任務。也可以調用shutdownNow,此時線程池會取消正在排隊等待處理的任務并且試圖中斷正在執行的線程。

            下面總結了在使用連接池時應該做的事:

            1、調用Executor類中靜態的newCachedThreadPool或newFixedThreadPool方法。

            2、調用submit來提交一個Runnable或Callable對象。

            3、如果希望能夠取消任務或如果提交了一個Callable對象,那就保存好返回的Future對象。

            4、當不想再提交任何任務時調用shutdown。

           除了常規的計算匹配文件數量外,這個程序打印出執行過程中池中的最大線程數量。但從ExecutorService接口不能得到這個信息。因此,我們必須將pool對象轉型成一個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;
          }

          posted on 2012-06-19 09:31 順其自然EVO 閱讀(178) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2012年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 江城| 崇阳县| 宜君县| 西充县| 景谷| 永川市| 东阳市| 昌吉市| 湘潭市| 塘沽区| 万山特区| 浮山县| 洞头县| 碌曲县| 永丰县| 毕节市| 托克逊县| 林西县| 白城市| 漳浦县| 秀山| 涿州市| 鄂尔多斯市| 塔城市| 南丹县| 五寨县| 江城| 威远县| 资中县| 胶州市| 潞城市| 山东| 永丰县| 松江区| 岚皋县| 余干县| 盖州市| 高尔夫| 濮阳县| 祁阳县| 德令哈市|