Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

290
Views
Using a threadpool to add in to a list

I am trying to read a file and add each line to a list.

Simple drawing explaining the goal

Main class -

public class SimpleTreadPoolMain {

  public static void main(String[] args) {
    ReadFile reader = new ReadFile();
    File file = new File("C:\\myFile.csv");
    try {
        reader.readFile(file);
    } catch (IOException e) {
        e.printStackTrace();
    }
  }
}

Reader class -

public class ReadFile {

ExecutorService executor = Executors.newFixedThreadPool(5);//creating a pool of 5 threads

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

void readFile(File file) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
        String line;
        while ((line = br.readLine()) != "") {
            Runnable saver = new SaveToList(line,list);  
            executor.execute(saver);//calling execute method of ExecutorService 
        }
    }

    executor.shutdown();  
    while (!executor.isTerminated()) {   }  

}

}

Saver class -

public class SaveToList<E> implements Runnable{

List<E> myList;

E line;

public SaveToList(E line, List<E> list) {
    this.line = line;
    this.myList = list;
}

public void run() {
    //modify the line
    myList.add(line);

}
}

I tried to have many saver threads to add in to a same list instead of one saver adding to the list one by one. I want to use threads because I need to modify the data before adding to the list. So I assume modifying the data would take up some time. So paralleling this part would reduce the time consumption, right?

But this doesn't work. I am unable to return a global list which includes all the values from the file. I want to have only one global list of values from the file. So the code definitely should change. If one can guide me it would be greatly appreciated.

Even though adding one by one in a single thread would work, using a thread pool would make it faster, right?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Using multiple threads won't speed anything up here.

You are:

  • Reading a line from a file, serially.
  • Creating a runnable and submitting it into a thread pool
  • The runnable then adds things into a list

Given that you're using an ArrayList, you need to synchronize access to it, because you're mutating it from multiple threads. So, you are adding things into the list serially.

But even without the synchronization, the time taken for the IO will far exceed the time taken to add the string into the list. And adding in multithreading is just going to slow it down more, because it's doing work to construct the runnable, submit it to the thread pool, schedule it, etc.

It's simpler just to miss out the whole middle step:

  • Read a line from a file, serially.
  • Add the list to the list, serially.

So:

try (BufferedReader br = new BufferedReader(new FileReader(file))) {
    String line;
    while (!(line = br.readLine()).isEmpty()) {
        list.add(line);
    }
}
over 4 years ago · Santiago Trujillo Report

0

You should in fact try if it's worth using multi threading in you application, just compare how much time it takes to read the whole file without any processing on rows done, and compare it with the time it takes to process serially the whole file.

If your process is not too complex my guess is it is not worth to use multi threading.

If you find that the time it takes is much more then you can think about using one or more threads to do the computations.

If so, you could use Futures to process batches of input strings or maybe you could use a thread safe Queue to send string to another process.

private static final int BATCH_SIZE = 1000;

public static void main(String[] args) throws IOException {

    BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("big_file.csv"), "utf-8"));


    ExecutorService pool = Executors.newFixedThreadPool(8);
    String line;
    List<String> batch = new ArrayList<>(BATCH_SIZE);
    List<Future> results = new LinkedList<>();
    while((line=reader.readLine())!=null){
        batch.add(line);
        if(batch.size()>=BATCH_SIZE){
            Future<Object> f = noWaitExec(batch, pool);
            results.add(f);
            batch = new ArrayList<>(BATCH_SIZE);
        }
    }
    Future<List> f = noWaitExec(batch,pool);
    results.add(f);

    for (Future future : results) {
        try {
            Object object = future.get();
            // Use your results here 
        } catch (Exception e) {
            // Manage this....
        }
    }


}
private static Future<List> noWaitExec(final List<String> batch, ExecutorService pool) {
    return pool.submit(new Callable<List>() {
        public List call() throws Exception {
            List result = new ArrayList<>(batch.size());
            for (String string : batch) {
                result.add(process(string));
            }
            return result;
        }

    });
}

private static Object process(String string) {
    // Your process .... 
    return null;
};

There are many other possible solutions (Observables, ParallelStreams, Pipes, CompletableFutures ... you name it), still I think that most of the time spent is the time it takes to read the file, just using a BufferedInputStream to read the file with a big enough buffer could cut your times more then parallel computing.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!