• Post Reply Bookmark Topic Watch Topic
  • New Topic

Schronize/concurrency: .read only heap objects

 
Kalyan avvaru
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi
Can anybody please explain....does synchronization of of any code really matters when that code is only accessing heap object in a read only way.
For eg: a datasource instance object in a servlet. Why as a principle is a good practice not to declare a instance level objects in a servlet. As I see its only a issue if the code is doing some changes to that instance level object. Here in this case a datasource object will be used only to get a new connection. Isn't it
a over generifying the principle ?
 
Jim Hoglund
Ranch Hand
Posts: 525
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are correct that truly read-only objects do not benefit from synchronization,
as well as objects that will be accessed by only one thread. But remember that
objects are synchronized, not methods. For success, all methods must wait for
the object's lock, even those that only read the object, if it can be changed by
another thread. If just one accessing method does not synchronize, there can
be nasty surprises.

Jim ...
 
Kalyan avvaru
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim Hoglund wrote: But remember that
objects are synchronized, not methods.


Can you please explain more on the above quote?
Do you mean its the object that has lock, which is required to be acquired by any code that has been declared to be a synchronized block?
To my knowledge you cant attribute object's declaration with 'synchronized' keyword..only code blocks/methods.

But i think it seemed more like common sense to have an inversion of control where the object itself force the code to acquire a lock, there by
what ever code trying to access the object need to acquire lock on that object.
It doesnt seem an impossible idea...and may find good use cases for it.

Am I overlooking any issue here....why java hasnt included this feature???
 
Jim Hoglund
Ranch Hand
Posts: 525
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, since wait() and notify() are Object methods, synchronized is all about
securing the lock of an instance. The two methods below are equivalent
where the first one just requires less typing. As to forcing all references to be synchronized, there are cases where this
would be a problem. A friendly warning from the IDE would be nice, however.

Jim...

 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In your example without synchronization how do you publish the data source state to other threads without synchronization (can be done) , such that any reading thread can see your object.

Synchronization actually does two things the first is the more obvious one the second establishes happens before ordering if you want to write from one thread and read from another you must do this. There are other ways to achieve this proper use fences, final, static, volatile, Atomic's etc etc but there are gotchas. Reads cross threads of immutable variables can be done but the devil is in the detail of "thread immutable" even final has gotchas.

Why ... if you have an integer (God forbid it was a long ;-) or an object ) , and thread A sets sets it to 5, now thread B only ever reads this int but sees 0 (thread A would still swear its 5). (Fixes with out sync for this would be an atomic integer or the volatile keyword or if your careful final. )

Your first thread must publish all writes and your reading thread must accept them "establish happen before ordering". Think of it this way thread A must publish all writes it may have cached and thread B ignore any reads it may have cached (The real problem is way,way more complicated than this, caching may be nothing to do with the problem eg compiler optimisations etc etc ), now you could have both threads never cache but the result is slower Java.

Java memory model links

I suggest you read JSR 133 and try to gain an understanding of what the volatile keyword means.

As to why some of this isn't done for you, its easy to see how to make the language must simpler round threading but the cost would be performance, some helper stuff is there if you look hard enough.
 
Jim Hoglund
Ranch Hand
Posts: 525
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chris, I'm confused. Are you describing alternatives to using the
'synchronized' key word? wait() and notify() apply only to obejcts,
so locking on primitives is a bit of a problem, but you can just use the
wrapper classes. And about hiding or publishing changes; on a single JVM,
all threads can see all objects, depending on your code, of course. It's what
can be done with those objects and when that's controlled by synchronization.
Am I missing your point(s)?

Jim...
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was describing alternatives to the property of the synchronized keyword that goes to visibility, (google synchronized and visibility), everyone seems to get locking but many struggle with visibility (the synchronized keyword does two things) i.e. I believe the original question attempts to define a read only scenario where locking is unnecessary (lockless) but I'm not confident they have considered visibility.

e.g. read this synchronization particularly "Publication and Data visibility"

The key point is stick to the rules everything is simple but the initial question is of the format why should I stick to the rules, can I not bend them a bit and the answer is no.

Your point all threads can see all objects ... my point but not necessarily their current state and its possible for threads to see the same object at the same time in different states.

i.e. If two threads can access the same object or primitive and one changes it the change may not be seen or partially seen by another thread, unless you follow the visibility rules of the Java Memory Model.

PS the following lines were ever so slightly different (I didn't mention it coz it was picky), the first puts a flag on the method (ACC_SYNCHRONIZED) the second generates the expected monitor locking byte code, so in theory the first results in less byte code (well it did the last time I could be bothered to look may have changed now)

 
Kalyan avvaru
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Chris
Thanks for that input. The data visibility and synchronization is really an eye opener to me. But still its not clear to me why it matters for read only objects.
None of the user threads are changing datasource state directly. I see datasource object as a utility entity, and its state management will be abstracted to its users. There is no change in a state by any of its user threads..(directly atleast). May be to deal with visibility issue, which in this case as an utility library it should be dealt by datasource object itself, by having its state modified(if any thing it had to...which is again irrelevant for user threads) in a synchronized way way. But for a user thread(s), datasource object is still a read-only object.

I have a strong feeling...my conceptual understanding of threads is fundamentally flawed. Please enlighten me.

Regards
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First of all I suspect your data source isn't an immutable object even if its public interface is , early versions of java String suffered this issue there public interface allowed no change but actually they tried to sneak some internal change unfortunately this was a visibility issue for threads.

Now how does your data source come into life , how are those writes to get the data source to its initial state published to other threads, the data source could defend its self by synchronizing all methods kind of in the way all early java collections did but that has issues (see vector vs arraylist)

Consider your reference to the data source how does that come into life e.g. initialise to null then write new object reference (be careful just because your code looks one step it may not be thread atomic) what if that reference write is never seen by any of your non modifying, only reading threads, how can it defend its own reference (can be done synchronize the get reference, volatile reference ;-) ). See the double checked locking example at the end for some issues round 'just' reading a reference from another thread,.

If thread A modifies data source even in a synchronized way as you put it and thread B reads unsynchronized the rules are quite complex as to if thread B will see any of the changes made by thread A. In terms of synchronization is A and B should both synchronize on the same object.

Consider a very common example a thread A that runs polling a public member boolean variable initially true for changing to false, thread B sets this variable (via a synchronized method) to a new value false which thread A is intended to see and stop BUT thread A doesn't read via a synchronized so the write of B can be missed and it loops forever.

This a really complicated subject perhaps the most complex in java and the only way to learn it is to start with lots of simple code gotcha examples. My first recommendation is you don't learn it at all and stick to a few basic threading rules but if you do start by looking at the issues round the famous double checked locking idiom as covered in many books and web sites.

eg double checked locking
 
Jim Hoglund
Ranch Hand
Posts: 525
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Chris. You're comments aim a bit over my pay grade. The link you provided
says, "In general, correct synchronization solves the visibility problem..." Unless
you see some holes in this idea, it works for me.

Jim ...
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It does correct synchronization solves all the problems and its simple, the issue is when you try to get clever for instance I don't need to synchronize because its read only or there is another one some more advanced threaders try where they break the you have to synchronize on the same object rule. I think the trick is not to try and create your own exceptions to the rules unless you really know what your doing.
 
Kalyan avvaru
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chris....I have one word for you...."WOW"
I know threading is the most complicated concept. But thinking in threads in attempt to hack your way around..., seems one needs be an direct descendant of some almighty.

May be "ignorance is the bliss" applies here.
 
Kalyan avvaru
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry ...
Can you please elucidate how to visualize threading workhorse, for a better understanding.
What are the basic principles that need to be followed for writing thread safe applications.
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'll try to right a beginners guide and post it later (its quite hard to do)

The definite guide is JSR133 / Java Memory model.

This looked a reasonable read and seemed to cover a lot of key points ..

overview

Basically if you write from one thread and read the same object / primitive from another then synchronize on a common object
or in legalise ;-)
An unlock on a monitor happens before a subsequent lock on the same monitor


(Disclaimer: There are other ways to achieve this)

 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!