I have a data var, monthArray, that is read by multiple consumers and periodically updataed by a single periodicall scheduled updater thread. All asynchronously.
I have considered both of these options to perform the update safely.
ArrayList<String> tempArray = ModelJob.getDistinctMonths(user, true);
synchronized (monthArray) {
monthArray = tempArray;
}
or
synchronized (monthArray) {
monthArray = ModelJob.getDistinctMonths(user, true);
}
The idea behind the first one being that the ModelJob.getDistinctMonths(user, true); call is time consuming and I dont want to hold the synchrinzation to block for longer then it has to, only for the quick reassignment of the old array with the updated array. However seems to be a obfuscated, and I only want to do it if completly nessecary. Can anyone give me any insight into how the jvm handles this synchrization and weather or not doing the former will give me any increase in performanace? Basically Im asking if the jvm would block for the whole static ModelJob call, or if it is able to get away with only blocking for the reassignment and be safe, and if so, if it is smart enought to do so.
assuming that you don’t need the synchronization around the
getDistinctMonths()call (that call is thread-safe, and you don’t need atomicity around the call and the assignment), then you can just synchronize around the assignment (and yes, the blocking is only scoped to the synchronized block, otherwise the syntax would be pointless). Note, @JohnVint brings up a good point that you should not synchronize on themonthArrayreference as it is being modified. you must synchronize on a separate object instance which does not change.Lastly, you could remove the synchronization block and make the
monthArraymember volatile and achieve the same results.