wayne forrest wrote:Also assume... that the data stored will be Objects and not primitives.
If this makes a difference, then the answer to the question must be "It depends". It depends on the semantics of the objects in question. If they are immutable, then probably they act like primitives in that you won't see partial changes to their state.
Or perhaps you were concerned about references to objects changing in blocks which potentially should be synchronized? Again this leads me to believe that there's more to this question than just Yes or No.
If you have to ask the question the answer is you need both, ask yourself the question why is there a WriteLock and a ReadLock.
Even if you use 32bit primitives to avoid word tearing you still have problem of correctly publishing your value. Immutable is a lovely idea but you have to fully understand the difference between thread immutable and just what the average programmer calls immutable.
The problem is if you read without a lock your code may just read a previously cached value for a number of reasons (Java optimisation, CPU caching).
I previously had to fix an open source library where some one decided that they only needed a sync on a setter and not the getter which was followed up by a bug report where the getter failed to see the result of a previous set on another thread.
I strongly urge you not to attempt to code like this, it is possible to do i.e. correct use of final, static, volatile, new JAVA Fence API etc etc but unless this is a critical optimisation is almost certainly a waste of time and incredibly easy to get wrong.
"Eagles may soar but weasels don't get sucked into jet engines" SCJP 1.6, SCWCD 1.4, SCJD 1.5,SCBCD 5
Well I will say it depends on a case to case basis. If all your threads are doing is updating values in a map, they don't care (Read) what other threads are doing with that object, we would only sync setter. But in case when you have a race condition, lilke the famous producer consumer problem you have to synchronize access to object and you will have to lock read and write access.
My answer would be that read operations also should be accessed in synchronized manner. The reason for that is below:
Synchronization gives you 2 guarantees: 1) Locking : No thread can access the same code with same lock. 2) Visibility: The changes are visible to all threads at the same time.
It is for "visibility" part that you want to make the reads also synchronized.
Having said the above, I would suggest that you should use appropriate class from concurrency package as the concurrency classes typically allow reads without the big overread of synchronization.
Hope it helps.
You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop