/* * Copyright (c) 2001 Matthew Feldt. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided the copyright notice above is * retained. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES. */ /** * LineCounter.java * * Java Examples In A Nutshell Copyright (c) 2000 David Flanagan * Exercise 4-1: * Write a Java program that takes a list of filenames on the command line and * prints out the number of lines in each file. The program should create one * thread for each file and use these threads to count the lines in all the * files at the same time. Use java.io.LineNumberReader to help you count lines. * You'll probably want to define a LineCounter class that extends Thread or * implements Runnable. Now write a variant of your program that uses your * LineCounter class to read the files sequentially, rather than at the same * time. Compare the performance of the multithreaded and single-threaded * programs, using System.currentTimeMills() to determine elapsed time. Compare * the performance of the two programs for two, five and ten files. * * @author Matthew Feldt * @version 1.0, 02/13/2001 20:29 */ package com.feldt.examples.thread; import java.io.*; class LineCounter extends Thread { private long numLines; private File fileName; LineCounter(File f) { numLines = 0; fileName = f; } public void run() { countLines(); } public long getNumLines() { return numLines; } public String toString() { return fileName + ": " + Long.toString(numLines); } public long countLines() { try { LineNumberReader in = new LineNumberReader(new FileReader(fileName)); while(in.readLine() != null) ; numLines = in.getLineNumber(); in.close(); } catch(FileNotFoundException e) { System.err.println("LineCounter.countLines(): " + e.getMessage()); } catch(IOException e) { System.err.println("LineCounter.countLines(): " + e.getMessage()); } return numLines; } /** test class */ static class Test { /** simultaneously count lines from multiple files using threads */ static long threadCount(String[] fileList) throws InterruptedException { LineCounter[] lcThread = new LineCounter[fileList.length]; long begin; begin = System.currentTimeMillis(); // start timer // create and start a thread for each file for (int i = 0; i < fileList.length; i++) { lcThread[i] = new LineCounter(new File(fileList[i])); lcThread[i].start(); } // wait for all threads to complete and print the line counts for (int i = 0; i < lcThread.length; i++) { try { lcThread[i].join(); System.out.println(lcThread[i]); } catch(InterruptedException e) { throw e; } } return (System.currentTimeMillis() - begin); // return duration } /** sequentially count lines from multiple files */ static long sequentialCount(String[] fileList) { LineCounter[] lcThread = new LineCounter[fileList.length]; long begin; begin = System.currentTimeMillis(); // start timer for (int i = 0; i < fileList.length; i++) { lcThread[i] = new LineCounter(new File(fileList[i])); lcThread[i].countLines(); System.out.println(lcThread[i]); } return (System.currentTimeMillis() - begin); // return duration } /** shorthand method to throw an exception with the appropriate message */ protected static void fail(String msg) throws IllegalArgumentException { throw new IllegalArgumentException(msg); } public static void main (String[] args) { final String usage = "Usage: java LineCounter$Test [-s | -t] file ..."; int index = 0; boolean threaded = false, sequential = false; String[] fileList; try { // process and verify command line arguments if (args.length < 2) fail(usage); if (args[index].charAt(0) == '-' && args[index].length() == 2) switch (args[index].charAt(1)) { case 's': sequential = true; index++; break; case 't': threaded = true; index++; break; default: fail(usage); } // build file list if ((args.length-index) <= 0) fail(usage); fileList = new String[(args.length - index)]; for (int i = index, j = 0; i < args.length; i++, j++) { fileList[j] = new String(args[i]); } // if not specified on the command line - do threaded count if (! threaded && ! sequential) threaded = true; // run the selected line count if (sequential) System.out.println("Sequential execution time: " + sequentialCount(fileList)); else System.out.println("Threaded execution time: " + threadCount(fileList)); } catch(IllegalArgumentException e) { System.err.println(e.getMessage()); System.exit(-1); } catch(InterruptedException e) { System.err.println(e.getMessage()); System.exit(-1); } } } }