GeeCON Prague 2014*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes To synchronize or not to synchronize? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "To synchronize or not to synchronize?" Watch "To synchronize or not to synchronize?" New topic
Author

To synchronize or not to synchronize?

Bill Robertson
Ranch Hand

Joined: Mar 21, 2003
Posts: 234
I have a method in my Data class called read, I am sure most of you
are familiar with this. I cannot determine whether or not it needs
to be synchronized. In fact I have a few methods with the same issue.
It looks like this:

Now in order to read it must of course manipulate my file handle (raf), which I only have one of, and this of course spells out synchronization. But, it manipulates the file handle indirectly by calling
"this.getContractor(recordNumber)" which IS synchronized and by the way called by other methods. My question is do I still synchronize on the whole read method.
Here is another example. In this example I also indirectly manipulate
the file handle (raf) through "getAllContractors()" which is synchronized.
And again, do I need to synchronize the entire method.

My thinking is just as long as the file manipulation part is synchronized then the entire method does not need sychronized. But I am not 100% confident.
Thanks in advance!!!
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Bill,
Now in order to read it must of course manipulate my file handle (raf), which I only have one of, and this of course spells out synchronization. But, it manipulates the file handle indirectly by calling
"this.getContractor(recordNumber)" which IS synchronized and by the way called by other methods. My question is do I still synchronize on the whole read method ?

No. If getContractor(recordNumber) is synchronized, you don't need to synchronize read().
Now I must say that your design looks weird to me. If they add any field in the table (or just reorder them) or decide to access any other table with your Data class, it looks like you may prepare yourself for much refactoring ...
Best,
Phil.
Bill Robertson
Ranch Hand

Joined: Mar 21, 2003
Posts: 234
thanks for the response. Big Help!!!
I choose not to use any form of dynamic/metadata for my columns.
I read them as is. This is based on feedback from other who have
scored rather high. Plus metadata makes code much harder to read.
And actually the way I have it set up refactoring would not really take
that long. How do you have it set up?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
No. If getContractor(recordNumber) is synchronized, you don't need to synchronize read().
Agreed, provided the object returned by getContractor() is not shared with any other threads. If getContractor() reads an RAF and creates a new Contractor object, you're fine. If on the other hand it accesses a cache of some sort, you may need to make a defensive copy of the data before you return it to the caller. Assuming that a Contractor is a mutable object, and other threads may try to change it.
I agree with Phil that the design looks a little weird. I'm not sure all those getXXX() methods really help, considering you just put everything in an array. Why not return an array in the first place? Another weird thing: you getContractors() method seems to return a List of all contractors. Meaning that you'll need to have enougth memory available for that, every time find() is called. Well if you're going to do that - why not just keep the data in memory all the time, and write to the file only when changes occur? The only objection most people have to this is that it takes more memory than rading from a file as needed. But your design requires just as much memory as if you'd kept everyting in memory all along, and you're doing a lot more I/O too. As long as you're using the memory, you might as well get rid of all that unnecessary file I/O. Or modify the design to not read everything into a List all at once. Personally I see no problem with putting everything in memory, and it can give really good performance. Others disagree, that's fine. But reading everything into memory each time find() is called is really the worst of both worlds - you're wasting both memory and speed, IMO. Of course, simplicity is more important than either of these, but the truth is the alternatives are not complex either.


"I'm not back." - Bill Harding, Twister
Bill Robertson
Ranch Hand

Joined: Mar 21, 2003
Posts: 234
You made a great point about making sure nobody else shares the contractor
being returned.
As far as returning the whole list everytime you last sentence sums it up
"Of course, simplicity is more important than either of these,...".
If there is anything I have learned from people who have breezed through
this its simplicity.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Simplicity would be to replace

with

And now you don't need a getAllContractors() method at all. Nor the memory to store the List in. Though you do need a getMaxRecNo() of some sort, but that should be pretty easy, as you must have something like that somewhere anyway...
[ November 17, 2003: Message edited by: Jim Yingst ]
Bill Robertson
Ranch Hand

Joined: Mar 21, 2003
Posts: 234
hhhhmmmmm, I have to think about this one. Because my getContractor()
hits the file each time so I have that overhead. Then also if my logic
between the for loop is lengthy that means I have to synch the entire
method because I perform a getContractor() each time. Also I of course
want to skip deleted records - but that should be no big deal the
way I have it designed but just one more thing to worry about.
Now, your basically saying I should have an instance variable that carrys
around all of the contractors and only refreshes itself on a write to
file. Correct?

great comments and suggestions - thank you.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Because my getContractor() hits the file each time so I have that overhead.
Is that significantly different from what you do in getAllContractors()? I can imagine ways that getAllContractors() might be optimized to read a bunch of contractors more efficiently, but my gut feeling is it's probably not a big difference.
Then also if my logic between the for loop is lengthy that means I have to synch the entire method because I perform a getContractor() each time. Also I of course want to skip deleted records - but that should be no big deal the way I have it designed but just one more thing to worry about.
I'm thinking that whatever logic that went into getAllContractors() in the first place can just go here instead. Does getAllContractors() need to be called rom anywhere else?
Now, your basically saying I should have an instance variable that carrys
around all of the contractors and only refreshes itself on a write to
file. Correct?

Well, there are two main options here. You can either read from the file every time you need to access data, or you can store it all in memory permanently. The first takes time, the second takes memory; either of these is OK. I just don't like the idea of reading everything from file into memory every time find() is called, which takes both time and memory. Personally I favor the latter, having a List of all contractor data as an instance variable. When changes are made to data, you write the changed data to the file, and update the data in the List. There's never really any need to update all the data from the file (after startup that is), unless (a) you're afraid your code might errooneously allow the List data to get out of sync from the file, or (b) some other process might be writing to the file while your program is running. In theory we shouldn't have to worry about either of these, but you may want to put in some safeguards; that's reasonable.
Note that in my previous code sample, it looks the same whether getContractor() is reading from a file, or accessing data from a List. I was trying to show that either way, you can write the find() method in fairly simple fashion, without requiring a big List in the find() method.
Bill Robertson
Ranch Hand

Joined: Mar 21, 2003
Posts: 234

Is that significantly different from what you do in getAllContractors()? I can imagine ways that getAllContractors() might be optimized to read a bunch of contractors more efficiently, but my gut feeling is it's probably not a big difference.

No. Optimize getAllContractors using a cache correct?

I'm thinking that whatever logic that went into getAllContractors() in the first place can just go here instead. Does getAllContractors() need to be called rom anywhere else?

True. Yes, get all contractors is called by other methods.
On using a cache. I took some time and looked up about a dozen messages
and all of them came to conclusion the caching was not necessary for this
project and probably won't gain you anything points wise (in fact you agreed upon this in one of the messages). Like you, I think its better having all of the data in an instance variable. But I have tested so much and I am running out of time. And like you said "either of these is OK."
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
No. Optimize getAllContractors using a cache correct?
Mmmm, not necessarily. Even with no cache, getContractor() would need to seek() each record individually since it assumes random access, while getAllContractors() can omit this since it knows it's accessing everything sequentially. That should be pretty minor though.
Yes, get all contractors is called by other methods.
Oh. (What other methods?) Well if that's the case, it may not be worth the time to refactor, if you've got everything else working well.
Re caching - no, it's certainly not required. And your reasons for not wanting to get into it now are perfectly valid. I maintain that it can be done pretty simply (though this may depend on other details of your design), but there's no need for it if your current design works. Good luck...
Bill Robertson
Ranch Hand

Joined: Mar 21, 2003
Posts: 234
as always, big thanks for your thoughts
 
GeeCON Prague 2014
 
subject: To synchronize or not to synchronize?