Hello,
This is my first post to the community. I have never really been one to ask of much help but I am stumped. I was asked to asked to write a word count program that received input from a scanner object. The input could consist of one or more file names relative or absolute paths. I am very new to the concepts of threads but I do understand that in order to produce a thread you must implement runnable (and utilize the run() to execute your action) or extend the thread class. However, my problems lies in the fact that you do not have a set number of files that you are processing so you cannot flat out initialize a specific number of runnable objects for that number of threads. I got around this fact by using a loop but it uses the same variable.

I am able to read the file names and give a word count for each and everything works all fine and dandy. I am required to print a total out at the end of the program of all the words counted. I get it to print but it is only the count for the last word. I understand that this is because within my run() method for my class that implements runnable i make a call to my setter for my total within my total class. Each time I run a new thread it initializes a new instance of the Total class, which I believe is my problem because the variable is reset. I also wrote my total methods as synchronized. I am at a complete loss on how to get around this and my code still function properly. I am coming back from a three long year break without touching java and now this new concept has got be baffled. I wrote a program without using threads very very easily. If anyone has any experience with this and does not mind to give me some advice then I would be very grateful. Thanks everyone.

Here is my code:

package com.threads.dada;

public class ThreadTester 
{
	
	public static void main(String[] args)
	{
		final int count;
		
		String fileName;
		
		FileNames fn = new FileNames();
		
		fn.setFileNames();
		
		count = fn.count();
		
		for(int i = 0; i <= count; i ++)
		{
			fileName = fn.getFileNames(i);
			
			if(i != (count))
			{
				Runnable r = new Threads(fileName, false);
				
				Thread t = new Thread(r);
				
				t.start();
				
			}
			else
			{
				Runnable r = new Threads(fileName, true);
				
				Thread t = new Thread(r);
				
				t.start();
			}
		}
	}
}
package com.threads.dada;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Threads implements Runnable
{
	public Threads(String fn, Boolean l)
	{
		filename = fn;
		last = l;
	}

	@Override
	public void run() 
	{
		
		tot = new Total();
		
		try
		{

				rf = new Scanner(new File(filename));
				
				while(rf.hasNext())
				{
					rf.next();
					count ++;
				}
				
				
				tot.setTotal(count);
				
				if(last == false)
				{
					System.out.println(filename + ":" + count + " ");
				}
				else if(last == true)
				{
					System.out.println(filename + ":" + count + " ");
					
					System.out.println("Total: " + tot.getTotal());
				}
				
				rf.close();
			
		}
		catch(FileNotFoundException e)
		{
			System.out.println("File " + filename + " was not found.");
		}
	}
	
	private String filename;
	private Boolean last;
	private Scanner rf;
	private int count = 0;
	private Total tot;

}
package com.threads.dada;

import java.util.*;

public class FileNames 
{	
	public void setFileNames()
	{	
		System.out.println("Enter a filename for a .txt or .java file.");
			
		in = new Scanner(System.in);
			
		filename = in.nextLine();
		
		while(filename.equals(""))
		{
			System.out.println("If you would like to exit, please enter exit at the command prompt.\n" +
					                "Please re-enter a filename for a .txt or .java file.");
			
			in = new Scanner(System.in);
				
			filename = in.nextLine();
			
			if(filename.equalsIgnoreCase("exit"))
			{
				System.exit(0);
			}
			
			
		}
		
		StringTokenizer st = new StringTokenizer(filename);
		
		count = st.countTokens();
		
		token = new String[count];
		
		i = 0;
		
		while(st.hasMoreTokens())
		{
			token[i] = st.nextToken();
			i++;
		}
		
		in.close();

	}
		
	public String getFileNames(int i)
	{
		return token[i];
	}
	
	public int count()
	{
		return (token.length - 1);
	}
	
	private Scanner in;
	private String filename;
	private String token[];
	private int count;
	private int i;

	
}
package com.threads.dada;

public class Total 
{
	private int total = 0; // count starts at zero

	public synchronized void setTotal(int amount)
	{ 
		total = amount;
	}
	
	public synchronized int getTotal()
	{
		return total;
	}

}

Recommended Answers

All 3 Replies

Bump?

Define a class (I'll call it YourThread) that extends Runnable and takes one argument to its constructor: the name of the file you want it to run on. Then in another class, the main/driver class, you can use a for loop and make a new instance of YourThread for each file you have.

http://www.go4expert.com/forums/showthread.php?t=4202

Thanks for the attempt to help me. However, if you look at the ThreadTester() class I am already doing essentially what you said. I just now had a chance to review this topic and my code and realized that I needed to set my total variable in the Total() class to static. The program now works correctly.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.