Example
Home ] Up ] The Executor Interface ] The ExecutorService Interface ] ScheduledExecutorService ] The Executors Class ] [ Example ]

 

 

Here's an example of the use of these interfaces and classes.

We've changed the previous MatchCounter example to use these features, and called it MatchCounterPoolDemo:

package threads;

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * A class to represent a Callable value that returns the count
 * of files in a directory and its subdirectories that contain
 * a specified keyword.
 */
public class MatchCounterPoolDemo implements Callable<Integer>
{
  /**
   * Main entry point
   */
  public static void main(String[] args)
  {
    Scanner in = new Scanner(System.in);
    System.out.print("Starting directory? ");
    String directory = in.nextLine();
    System.out.print("Keyword? ");
    String keyword = in.nextLine();
    
    ExecutorService pool = Executors.newCachedThreadPool();
    
    MatchCounterPoolDemo counter = 
                    new MatchCounterPoolDemo(new File(directory), keyword, pool);
    Future<Integer> result = pool.submit(counter);

    try
    {
      System.out.println( result.get() + " files contained '" + keyword + "'");
    }
    catch (ExecutionException ee)
    {
      ee.printStackTrace();
    }
    catch (InterruptedException ie)
    {
      System.err.println("Execution interrupted");
    }
    
    pool.shutdown();
    
    int largestPoolSize = ((ThreadPoolExecutor) pool).getLargestPoolSize();
    System.out.println("Largest pool size: " + largestPoolSize);
  }
  
  /**
   * Creates a new instance of MatchCounterPoolDemo.
   *
   * @param directory the directory in which to start the search
   * @param keyword the keyword to search for.
   * @param pool the thread pool to use.
   */
  public MatchCounterPoolDemo(File directory, String keyword, ExecutorService pool)
  {
    m_directory = directory;
    m_keyword = keyword;
    m_pool = pool;
  }

  /**
   * Implements the required Callable method
   */
  public Integer call()
  {
    m_count = 0;
    try
    {
      // Get list of files in current directory that match the file filter
      File[] files = m_directory.listFiles( new FileFilter()
        {
          public boolean accept(File file)
          {
            return file.isDirectory() || file.getName().endsWith(".java");
          }
        }
      );
      
      // Create a results array
      ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>();
      
      // Go through the files, doing a recursive and multi-threaded search.
      for (File file : files)
      {
        if (file.isDirectory())
        {
          // Use another MatchCounterPoolDemo and another thread to search
          // this directory.
          MatchCounterPoolDemo counter = 
                            new MatchCounterPoolDemo(file, m_keyword, m_pool);
          Future<Integer> result = m_pool.submit(counter);
          results.add(result);
        }
        else
        {
          if (search(file))
            m_count++;
        }
      }
      
      // Go through the Future results and accumulate the counts
      for (Future<Integer> result : results)
      {
        try
        {
          m_count += result.get(); // Blocks until result available
        }
        catch (ExecutionException ee)
        {
          ee.printStackTrace();
        }
      }
    }
    catch (InterruptedException ie)
    {
      // Ignore
    }
    return m_count;
  }

  /**
   * Searches the specified file for a given keyword.
   *
   * @param file the file to search
   * @return true if the keyword was found in the file.
   */
  private boolean search(File file)
  {
    Scanner in = null;
    boolean found = false;
    try
    {
      in = new Scanner( new FileReader(file) );
      while (!found && in.hasNextLine())
      {
        String line = in.nextLine();
        if (line.contains(m_keyword))
          found = true;
      }  
    }
    catch (IOException ioe)
    {
      // Do nothing (results in found being returned false)
    }
    finally
    {
      if (in != null)
        in.close();
    }
    return found;
  }
  
  //////// Private data //////////
  private File m_directory;
  private String m_keyword;
  private ExecutorService m_pool;
  private int m_count;
}

which produces, under similar conditions to the previous one:

27 files contained 'thread'
Largest pool size: 3

(I added one file since the last output.)

 
The page was last updated February 19, 2008