An Example
Home ] Up ] The Callable Interface ] The Future Interface ] FutureTask ] [ An Example ]

 

 

Here's an example of the use of Callable, Future, and FutureTask.

This example (modified from an example in Core Java, Vol. 1, Fundamentals) is similar to the earlier BlockingQueueDemo example, except that it counts the number of files that contain a specified keyword.

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.Future;
import java.util.concurrent.FutureTask;

/**
 * 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 MatchCounter 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();
    MatchCounter counter = new MatchCounter(new File(directory), keyword);
    FutureTask<Integer> task = new FutureTask<Integer>(counter);
    Thread thread = new Thread(task);
    thread.start();
    try
    {
      System.out.println( task.get() + " files contained '" + keyword + "'");
    }
    catch (ExecutionException ee)
    {
      ee.printStackTrace();
    }
    catch (InterruptedException ie)
    {
      System.err.println("Execution interrupted");
    }
  }
  
  /**
   * Creates a new instance of MatchCounter.
   *
   * @param directory the directory in which to start the search
   * @param keyword the keyword to search for.
   */
  public MatchCounter(File directory, String keyword)
  {
    m_directory = directory;
    m_keyword = keyword;
  }

  /**
   * 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 MatchCounter and another thread to search
          // this directory.
          MatchCounter counter = new MatchCounter(file, m_keyword);
          FutureTask<Integer> task = new FutureTask<Integer>(counter);
          results.add(task);
          Thread thread = new Thread(task);
          thread.start();
        }
        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 int m_count;
}

When this program was run on my NetBeans Threads project's src directory, specifying 'thread' as the keyword to search for, it produced the following output:

26 files contained 'thread'
 
The page was last updated February 19, 2008