Java Multithreading – How to Collect and Process Data from Multiple Threads

javamultithreadingstatic

There is a Java program that reads a list of orders and for each order starts a thread that receives data from SQL and prints the list of items in a given order to an order_name.html. I want to write a class that would generate all_orders.html that contains a list of items and the quantity of each item in all orders.

This is pretty straightforward in a single threaded environment. Write relevant data to order_name.csv, once all threads stop – parse these files and if the item exists – increment counter, else – add it to the list and set counter to 1. Once all files are parsed – create the report.

How can I do this in a multithreaded case? First, is it safe to create a private static list<items(String name, int count)> and search/modify it from multiple threads? How to check that all threads finished, the list<items> is complete and I can start preparing all_items.html? Is there a better method than a static list?


Edit: The program is multithreaded for historical reasons and to speed up processing multiple orders. The all_orders.html will be prepared using a single thread. What is the correct way to pass information to this thread. Specifically that order "a" has 2 items "foo" and 5 items "bar". And at the end that this order is fully processed and it has no additional items.

Best Answer

First, is it safe to create a private static list and search/modify it from multiple threads?

No. At the very least you'll want to use one of the concurrent collections. This may not be enough. For example, if you need to execute multiple operations against the list before any other thread touches it, you'll need some other sort of locking.

How to check that all threads finished, the list is complete and I can start preparing all_items.html? Is there a better method than a static list?

There are lots of ways to do this. If you know how many writing threads there are, a CountDownLatch might be a good solution for you. What you do it have the processing thread wait on the latch and each writer will update the latch when it's complete.

A static list will work but it's generally preferred to pass the list to the things that will write to it in the constructor.

Per first 2 comments, here's a simple design that should be safe:

In the main thread, generate an array of lists where the size of the array. For each slot, put a new CopyOnWriteArrayList in it, create a new Runnable and pass the array to it (store the reference in a final) and start the Thread. When all the threads complete, you can then loop over the content of the lists in the array. This might be slightly overkill but you don't want to be debugging crazy threading issues and it might work on one machine and fail on another if it's not totally solid.