qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          基于線程池的匹配文件數(shù)量計(jì)算

           除了常規(guī)的計(jì)算匹配文件數(shù)量外,這個(gè)程序打印出執(zhí)行過(guò)程中池中的最大線程數(shù)量。但從ExecutorService接口不能得到這個(gè)信息。因此,我們必須將pool對(duì)象轉(zhuǎn)型成一個(gè)ThreadPoolExecutor類(lèi)對(duì)象。

          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;
          }

          構(gòu)建一個(gè)新的線程的代價(jià)還是有些高的,因?yàn)樗婕芭c操作系統(tǒng)的交互。如果你的程序創(chuàng)建了大量生存期很短的線程,那就應(yīng)該使用線程池。一個(gè)線程池包含大量準(zhǔn)備運(yùn)行的空閑線程。你將一個(gè)Runnable對(duì)象給線程池,線程池中的一個(gè)線程就會(huì)調(diào)用run方法。當(dāng)run方法退出時(shí),線程不會(huì)死亡,而是繼續(xù)在池中準(zhǔn)備為下一個(gè)請(qǐng)求提供服務(wù)。

           

            執(zhí)行器(Executor)類(lèi)有大量用來(lái)構(gòu)建線程池的靜態(tài)工廠方法,下表給出了一個(gè)總結(jié)。

            newCachedThreadPool、newFixedThreadPool和newSingleThreadExecutor這三個(gè)方法返回ThreadPoolExecutor類(lèi)(這個(gè)類(lèi)實(shí)現(xiàn)了ExecutorService接口)對(duì)象。

            向線程池提交任務(wù)的方法為:將一個(gè)實(shí)現(xiàn)Runnable或Callable接口的對(duì)象提交給ExecutorService:

            Future<?> submit(Runable task)
            Future<T> submit(Runable task, T result)
            Future<t> submit(Callable<T> task)

            線程池會(huì)在適當(dāng)?shù)臅r(shí)候盡早執(zhí)行提交的任務(wù),調(diào)用submit時(shí)會(huì)返回一個(gè)Future對(duì)象,用以查詢?cè)撊蝿?wù)的狀態(tài),或者取消該任務(wù)。

            第一個(gè)submit方法提交一個(gè)Runable對(duì)象返回一個(gè)Future<?>,可使用該對(duì)象調(diào)用isDone、cancel、或者isCancelled來(lái)查詢?nèi)蝿?wù)狀態(tài)。但是此Future對(duì)象的get方法在任務(wù)完成的時(shí)候知識(shí)簡(jiǎn)單的返回null

            第二個(gè)版本的submit方法同樣提交一個(gè)Runable對(duì)象,并且返回Future的get方法在任務(wù)完成的時(shí)候返回傳入的result對(duì)象

            第三個(gè)submit方法提交一個(gè)Callable對(duì)象,并且返回的Future對(duì)象將在計(jì)算結(jié)構(gòu)、準(zhǔn)備好的時(shí)候得到它。

            當(dāng)想要注銷(xiāo)一個(gè)線程池,可調(diào)用shutdown方法,該方法啟動(dòng)該線程池的關(guān)閉序列。此時(shí)線程池并不是馬上就壯烈犧牲了線程也沒(méi)了,而是等待所以任務(wù)都完成以后,線程池中的線程才會(huì)死亡,被關(guān)閉的執(zhí)行器不再接受新任務(wù)。也可以調(diào)用shutdownNow,此時(shí)線程池會(huì)取消正在排隊(duì)等待處理的任務(wù)并且試圖中斷正在執(zhí)行的線程。

            下面總結(jié)了在使用連接池時(shí)應(yīng)該做的事:

            1、調(diào)用Executor類(lèi)中靜態(tài)的newCachedThreadPool或newFixedThreadPool方法。

            2、調(diào)用submit來(lái)提交一個(gè)Runnable或Callable對(duì)象。

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

            4、當(dāng)不想再提交任何任務(wù)時(shí)調(diào)用shutdown。

           除了常規(guī)的計(jì)算匹配文件數(shù)量外,這個(gè)程序打印出執(zhí)行過(guò)程中池中的最大線程數(shù)量。但從ExecutorService接口不能得到這個(gè)信息。因此,我們必須將pool對(duì)象轉(zhuǎn)型成一個(gè)ThreadPoolExecutor類(lèi)對(duì)象。

          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) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2012年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 三都| 林芝县| 友谊县| 喀喇沁旗| 山丹县| 名山县| 康定县| 呼和浩特市| 万山特区| 德江县| 永善县| 顺平县| 建德市| 灌阳县| 合川市| 噶尔县| 旅游| 福安市| 清镇市| 长宁区| 兴和县| 北票市| 乌海市| 南京市| 九江市| 乌拉特前旗| 三亚市| 远安县| 永嘉县| 轮台县| 平安县| 江川县| 宿松县| 拜城县| 三门峡市| 彭水| 眉山市| 靖边县| 鄂伦春自治旗| 湾仔区| 闽清县|