Here's a basic question about multi-threading in Java: I have a very big mutable data structure (a tree, to be exact) and I understand that if I want to modify this data structure concurrently from two different threads, I need to use locks and/or other kinds of thread safety.
However, in my case, the two threads don't need to modify the data structure at the same time; rather, thread A, which normally owns the data structure, should temporarily pass the latter to thread B, and thread B should pass the data structure back to thread A after having done some long-running modifications on it.
Is it thread-safe to pass this mutable data structure back and forth between threads, if it's guaranteed that the threads do not modify the data at the same time?
You should use volatile keyword to keep the variable updated among all threads. Using volatile is yet another way (like synchronized, atomic wrapper) of making class thread safe. Thread safe means that a method or class instance can be used by multiple threads at the same time without any problem. Save this answer.
A MessageService object is effectively immutable since its state can't change after its construction. So, it's thread-safe. Moreover, if MessageService were actually mutable, but multiple threads only have read-only access to it, it's thread-safe as well.
Stack Memory and Threads Secondly, it stores local primitives and local object references on the stack. In addition, it's important to realize that every thread, including the main thread, has its own private stack. Therefore, other threads do not share our local variables, which is what makes them thread-safe.
If you can guarantee that the threads don't modify the tree at the same time (i.e. by atomically passing over the only reference to the tree), it is fine from a thread-safety point of view.
Data visibility / consistency is another concern, though. Unless all fields in the tree are (recursively) declared volatile
, changes made by one thread may not become visible to the other thread. To avoid, make sure a monitor (which acts as a memory barrier and ensures that all writes becomes visible) is acquired when the threads exchange ownership of the tree.
Yes, what you are describing would work just fine as long as you take specific steps to avoid memory consistency errors when you're passing the object between threads. Using locking is one way to achieve this, but there are other -- less expensive -- ways.
The tutorial is a good starting point.
Basically, you need to ensure that when thread A is passing the object to thread B, all changes by A happen-before B accesses the object.
There's more in the JLS, but it's rather technical.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With