0

(All of this is in a multi-threaded environment) I have a scenario in my code which requires me to update the static variables in a class. Now, based on the latest combination of the variables, the code might enter one flow or the other. I've used synchronize to allow only one thread to update the variables. Since, I also want any other thread to notice the most recent value only, I've declared the two variables as volatile too. I've been reading about the differences b/w the two keywords, and I believe that both of them have to be used to achieve what I want. The read accesses are not synchronized, only the part where I write to the variables is synch-ed.

I am new to the multithreading domain in Java, and would like to know if this is a good practice. Is there a better (more efficient) way of achieving this in Java?

lazyloader
  • 157
  • 2
  • 10
  • 1
    There is no reason to make a variable `volatile` if all of the accesses to it are inside `synchronized` blocks. – Solomon Slow Feb 18 '19 at 16:04
  • Probably _not_ good practice to use `volatile` except in the special case of a single variable, whose meaning does not depend on the value of any other variable, and which never will be set to any "invalid" or "temporary" value, and which (of course) is shared between two or more threads. – Solomon Slow Feb 18 '19 at 16:07
  • The read accesses are not synchronized, only the updates are. Sorry, I should add that to the original post. My thinking behind writing it as volatile was that while the update is still happening, the other threads might read a stale value, which I don't want. – lazyloader Feb 18 '19 at 16:07
  • 1
    Re, "the read accesses are not synchronized." That probably is a mistake. If the write accesses need to be `synchronized`, then the reads almost certainly also need to be `synchronized.` – Solomon Slow Feb 18 '19 at 16:08
  • Won't that affect the performance too much? The app will be heavily multithreaded – lazyloader Feb 18 '19 at 16:09
  • If effects depend on a combination of variables, then you shouldn't rely on `volatile` for the read. – Mark Rotteveel Feb 18 '19 at 16:10
  • Mark, I see. Could you please elaborate on that a little bit, or redirect me to a source I can go through :) – lazyloader Feb 18 '19 at 16:11
  • 1
    Re, "Won't that affect the performance...?" If your only options are "slow" or "wrong," then you probably should go with "slow." – Solomon Slow Feb 18 '19 at 16:13
  • Re, "...Too much?" That's for you to decide. Usually the first step is to get something working (and by that, I mean,working _correctly_). Then, if it seems like you have a performance problem, you can measure the performance, and attempt to do something about it. Optimizing multi-threaded applications for high performance is a book-level topic. Not something that anybody can tell you how to do here. – Solomon Slow Feb 18 '19 at 16:16
  • Solomon I agree to both your comments, thanks! Could you please elaborate on your earlier statement about how read accesses also need to be synch-ed when write accesses are. What could happen in case of using volatile here? – lazyloader Feb 18 '19 at 16:18
  • Relevant link and possible duplicate [When to use volatile and synchronized](https://stackoverflow.com/questions/9851133/when-to-use-volatile-and-synchronized) – Hovercraft Full Of Eels Feb 18 '19 at 17:00
  • 2
    In a nutshell, Any time a data object spans more than one memory location, there's a good chance that updating it can only be accomplished by a sequence of steps that cause the data to be _invalid_ for some brief amount of time. The purpose of _mutual exclusion_ (e.g., `synchronized` statements) is to prevent other threads from seeing those temporary, invalid states. Without mutual exclusion, a thread that merely wants to read some data could end up crashing the program (e.g., by following a bad pointer). Or, it could corrupt other data because of some wrong thing that it read. Etc. – Solomon Slow Feb 19 '19 at 14:06
  • @SolomonSlow Even in "safe" languages w/o "pointers" that can be bad, like Java, you can have an invalid index in an array which makes some thread read the wrong entry in a table, update the whole record, etc. – curiousguy Mar 06 '19 at 22:39

1 Answers1

0

You can use ReentrantReadWriteLock to handle this type of scenario.

Andrianekena Moise
  • 1,018
  • 7
  • 16