1

A question on using threads in java (disclaimer - I am not very experienced with threads so please allow some leeway).

Overview: I was wondering whether there was a way for multiple threads to add actions to be performed to a queue which another thread would take care of. It does not matter really what order - more important that the actions in the queue are taken care of one at a time.

Explanation: I plan to host a small server (using servlets). I want each connection to a client to be handled by a separate thread (so far ok). However, each of these threads/clients will be making changes to a single xml file. However, the changes cannot be done at the same time.

Question: Could I have each thread submit the changes to be made to a queue which another thread will continuously manage? As I said it does not matter on the order of the changes, just that they do not happen at the same time.

Also, please advise if this is not the best way to do this.

Thank you very much.

Saad Attieh
  • 1,396
  • 3
  • 21
  • 42
  • 1
    For your scenario, since Servlets are already multithreaded ( for each request a seperate thread is created and the request is processed ). So you could just create a simple Class for handling the XML operations and put some synchronized methods in it for retrieving or saving data. – Dreamer Jul 13 '13 at 15:35
  • you just need to make `synchronized` [the method changes](http://www.codeproject.com/Articles/616109/Java-Thread-Tutorial#syncmethod) the xml –  Jul 14 '13 at 06:58

3 Answers3

4

This is a reasonable approach. Use an unbounded BlockingQueue (e.g. a LinkedBlockingQueue) - the thread performing IO on the XML file calls take on the queue to remove the next message (blocking if the queue is empty) then processing the message to modify the XML file, while the threads submitting changes to the XML file will call offer on the queue in order to add their messages to it. The BlockingQueue is thread-safe, so there's no need for your threads to perform synchronization on it.

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
  • 1
    single Thread executor does exactly same thing which you have described so my +1 for Matt. – Vipin Feb 27 '14 at 15:02
1

You could have the threads submit tasks to an ExecutorService that has only one thread. Or you could have a lock that allows only one thread to alter the file at once. The later seems more natural, as the file is a shared resource. The queue is the implied queue of threads awaiting a lock.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
1

The Executor interface provides the abstraction you need:

An object that executes submitted Runnable tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. An Executor is normally used instead of explicitly creating threads."

A single-threaded executor service seems like exactly the right tool for the job. See Executors.newSingleThreadExecutor(), whose javadoc says:

Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.

Note that in a JavaEE context, you need to take into consideration how to terminate the worker thread when your webapp is unloaded. There are other questions here on SO that deal with this.

Community
  • 1
  • 1
Matt McHenry
  • 20,009
  • 8
  • 65
  • 64
  • What if there are multiple threads that are submitting tasks to a single threaded executor? Is there any guarantee that the tasks are submitted in the correct order? – Tan Yu Hau Sean Apr 20 '23 at 14:02
  • The docs say that it uses a queue internally, so if there is a happens-before relationship between the threads calling `Executor.execute()`, then yes. But that's a subtle thing -- search "java happens-before" and read up. :) – Matt McHenry Apr 21 '23 at 21:49