Threads that read from text files concurently and place data in arrays

10,814

Solution 1

If we first fix your file reading thread, so that the main work occurs in the run() method:

public class FileReader extends Thread {

  private final File file;
  private String[] lines;

  public FileReader(File file) {
    this.file = file;
  }

  @Override
  public void run() {
    // Read file here (populate `lines`)..
  }

  public String[] getLines() {
    return lines;
  }
}

Then we can utilise this in the main method, as follows:

public static void main(String[] args) throws Exception {
  List<FileReader> threads = new ArrayList<FileReader>();

  threads.add(new FileReader(new File("foo1")));
  threads.add(new FileReader(new File("foo2")));
  threads.add(new FileReader(new File("foo3")));
  threads.add(new FileReader(new File("foo4")));

  for (FileReader t : threads) {
    t.start();
  }

  List<String> allLines = new ArrayList<String>();

  for (FileReader t : threads) {
    t.join();
    allLines.addAll(Arrays.asList(t.getLines()));
  }    

  // File lines now in allLines
}

Solution 2

Three mistakes:

  1. ReadFile is a class implementing Runnable, so you should pass an instance to the Thread constructor:

    Thread thread1 = new Thread(new ReadFile("list1.txt", Global.array1),"thread1");

  2. Why create a Thread inside ReadFile? Remove that, no additional runner needed!

  3. The ReadFile constructor has an additional parameter threadName which has to be removed.

Solution 3

Your constructor signature for ReadFile:

public ReadFile(String filePath, String[] toArray, String threadName)

does not match with the calls in main (you are only providing String, String[]). I think you meant:

Thread thread1 =  new Thread(new ReadFile("list1.txt", Global.array1, "thread1"));
Thread thread2 =  new Thread(new ReadFile("list2.txt", Global.array2, "thread2"));
Thread thread3 =  new Thread(new ReadFile("list3.txt", Global.array3, "thread1"));
Thread thread4 =  new Thread(new ReadFile("list4.txt", Global.array4, "thread2"));

You were probably confused by the fact that ReadFile's constructor takes the threadName as the third parameter, but the Thread class itself also has a similar parameter.

Share:
10,814
Ryan
Author by

Ryan

Updated on June 05, 2022

Comments

  • Ryan
    Ryan almost 2 years

    The goal of this code is to run four threads, which will open four text files, read the words from them and then place them into a string array,

    Main problems i know of:

    1- I am not putting the concurrent function in the void run function, I want to be able to pass parameters into that function

    2- I am not sure if I am modifying the global arrays of strings or not either

    First is the main method:

     public static void main(String[] args) throws IOException 
        {
             //declare the threads
             Thread thread1 =  new Thread(ReadFile("list1.txt", Global.array1,"thread1"));
             Thread thread2 =  new Thread(ReadFile("list2.txt", Global.array2,"thread2"));
             Thread thread3 =  new Thread(ReadFile("list3.txt", Global.array3,"thread1"));
             Thread thread4 =  new Thread(ReadFile("list4.txt", Global.array4,"thread2"));
    
             /*error message from netbeans: cannot find symbol
                symbol:   method ReadFile(java.lang.String,java.lang.String[])
    
                it says it for every delcaration of the thread*/
    
    
             thread1.start();  //putting the threads to work
             thread2.start();
             thread3.start();
             thread4.start();
    
             thread1.join();   //telling the threads to finish their work
             thread2.join();
             thread3.join();
             thread4.join();
    
    
             // merging the arrays into one
             List list = new ArrayList(Arrays.asList(Global.array1));
             list.addAll(Arrays.asList(Global.array2));
             list.addAll(Arrays.asList(Global.array3));
             list.addAll(Arrays.asList(Global.array4));
             Object[] theArray = list.toArray();
    
               -------------------------etc----------------------------
    

    This is the "thread class" if my vocab is right

    public class ReadFile implements Runnable
    {
        public void run(){
                //I should get stuff here, that's my problem!!!!
        }
    
    
        private String path;
        Thread runner;
    
        public ReadFile(String filePath, String[] toArray, String threadName) throws IOException
        {
            String path = filePath;
            FileReader fr = new FileReader(path);
            BufferedReader textReader = new BufferedReader(fr);
    
            int numOfLines = readLines();  
            toArray = new String[numOfLines];
    
            int i;
            for (i=0; i<numOfLines; i++)
            {
                toArray[i]= textReader.readLine();    //place next line into string array
            }
    
            textReader.close();
        }
    
    
       int readLines() throws IOException
        {
            FileReader fr = new FileReader(filePath);
            BufferedReader bf = new BufferedReader(fr);
    
            String aLine;
            int noOfLines = 0;
    
            while((aLine = bf.readLine()) != null)
            {
                noOfLines++;
            }
            bf.close();
            return noOfLines;
        }
    
        }
    

    Finally i did a class for the global variable, and i don't know if it's a good idea

    public class Global 
    {
        public static String[] array1;
        public static String[] array2;
        public static String[] array3;
        public static String[] array4;
    }
    

    please let me know what you guys think, any help or explanations or tips would be greatly appreciated

  • Tudor
    Tudor over 11 years
    1. That's what he's doing. 2. I agree with this.
  • Arne Burmeister
    Arne Burmeister over 11 years
    1. no, he missed the keyword new before ReadFile!