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.

  • I'm a little confused. You're calling this a "single-threaded environment," but you're using multiple threads. – Robert Harvey Jun 17 '16 at 17:59
  • Why use multiple threads for this? – Dan Pichelman Jun 17 '16 at 18:02
  • This program processes each order and creates order_name.html in its own thread, so the program is multithreaded. I want to add a feature that combines data from all orders. This part should run as a single thread after all other treads finished processing data. A simple hack would be to start a new thread, parse each order_name.html and create an all_orders.html based on that. However, I don't want to read these files given that I already have the data in memory. – sixtytrees Jun 17 '16 at 18:04
up vote 3 down vote accepted

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.

  • Is it safe to create an listOfItems[] alllOrders = new listOfItems[numberOfOrders], start a thread per order and assign it a number, within each tread prepare a listOfItems and set alllOrders.set(threadNumber, this.listOfItems)`? In other words is it safe to manipulate an Array from multiple threads if each thread only manipulates its own index? – sixtytrees Jun 17 '16 at 18:41
  • I think it's probably safe in that the each thread has it's own list and therefore each list will only be updated from one thread. You might have some issues, however. Each one is allowed to have it's own cache of memory. These are not required to be updated unless you put a synchronized block around access (read or write) so you could end up with stale data. Your scheme might work but I'm a little hesitant to say it will for sure. I'll update my answer with one possible design based on yours. – JimmyJames Jun 17 '16 at 18:54

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.