Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

NX: URLyBird Data class question

 
Katie Kelly
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello. I've been following this board for a while and it has been very helpful. Thanks!
I am trying to decide whether or not I should implement the Data class as a singleton. I've seen on this forum that a lot of people have implemented the Data class as a singleton, so I'm thinking that approach through. Given my current design, I don't think that a singleton will buy me anything in terms of thread safety, but I wanted to run it by someone to get a second opinion.
In my current design, my Data class uses a RandomAccessFile object to interact with the database file. Each client gets its own instance of a class called DataManager which has an instance of Data. DataManager implements the "business methods" for the application (like reserveRoom()) and it makes the calls to lock() and unlock() on Data. Data has a static WeakHashMap to keep track of locks. What would implementing Data as a singleton buy me in this design?
Thanks in advance!
Katie Kelly
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Katie,
Welcome to the ranch. I just cleared the exam recently. My design is quite similar to yours except that I used client side locking instead of the business method on the server calling lock, unlock, and islocked method and got full points for it. Mind you, others like Ken Krebs have implemented server side locking same as you and still gotten full points. I am not sure if there are any benifits to using the data class as a Singleton. If anything, it should make the program noticably slower, but that is not a criteria for passing this exam.
My two cents, stay with what you have.
Regards.
Bharat
 
Nicholas Cheung
Ranch Hand
Posts: 4982
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Katie,
In fact, since we dont have a DB as a result we need to consider the thread safety in our programs, I do not think that Singleton will help much in your design.
If you are in the design phase (less codes are developed), I guess it is a good habit to have a singleton DataManager to manage the data access (Data class). It seems better because you show that each function has an object to manage it.
However, as from your post, if you are already in coding phase (or maybe even finsih the major implementation), then I do not think it is worth to make such changes. Just keep going on what you have on hand.
Hope this help.
Nick.
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Katie,
Your design looks perfect. Just a few questions to make sure :
Each client gets its own instance of a class called DataManager which has an instance of Data.

Each DataManager gets its *own* Data instance, right ? And you use Data to track the client in your WeakHashMap ?
How do you synchronize access to your file ?
Did you implement a cache ? If true is it static as your WeakHashMap is ?
Regards,
Phil.
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12014
220
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Katie,
Welcome to JavaRanch.
I do not believe that the Data class should be implemented as a Singleton - it limits your options for future enhancements.
Take a look at this thread - Peter den Haan gives some very useful links to some interesting articles regarding Singleton use (or overuse).
Regards, Andrew
 
Katie Kelly
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for all of your responses!
To answer Phil's questions. Yes, each DataManager gets its own Data instance and I use Data to track the client in my WeakHashMap.
I'm still a little unsure about synchronizing access to the file. If every client has its own instance of Data and if I'm not spawning additional threads that will interact with Data from my clients (or anywhere else) then it seems like making the methods on Data synchronized won't matter because there will never be two objects calling methods on Data at the same time. I'm making a lot of assumptions there, though. Maybe it is safer to synchronize the methods on Data.
Also, I decided not to implement a cache. I probably would do that in real life, but the requirements didn't say anything about performance. I thought it would be better to keep things as simple as possible.
Thanks!
Katie
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Katie,
then it seems like making the methods on Data synchronized won't matter because there will never be two objects calling methods on Data at the same time.

You're 100% correct. I was thinking of synchronizing the file access. If you have one RAF instance per Data instance and one Data instance per client, you're OK with no synchronization as far as multithreading is concerned. At the RAF level, write collisions are excluded too thanks to the locking mechanism. The only remaining issue is dirty reads : one client writes a record in the same time another reads it. Dirty reads are acceptable though, so you are still OK with your design IMO, but you could mention it in your choices.txt file.
Best regards,
Phil.
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Katie,
I have to caution you a bit here! Even though my design is similar to yours, I explicitly synchronize on the file pointer during any read/write operation. Think about it, if you are using RMI, you do not know which thread will be running which Data class instance and for how long? If you don't explicitly synchronize around the file pointer during read/write, even though you have separate instances of Data class per client, you run the risk of the file pointer being moved in the middle of a physical record read/write operation. It took me some time to realize this and fully understand it. I think Phil is doing the Socket based implementation where RMI doesn't come into play.
Hope this helps.
Bharat
 
Katie Kelly
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bharat,
I think I saw some posts about synchronizing on the file pointer earlier, but I am not clear on a few things. How can you access the actual file pointer of the RAF? If I synchronize all methods on Data would I be safe?
Thanks!
Katie
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bharat and Katie,
A so clear and nice thread which now becomes confusing... Did you it on purpose ? (Ok I am kidding and teasing you a bit ). But I wonder though...
Bharat (about synchronizing on the RAF) :
I think Phil is doing the Socket based implementation where RMI doesn't come into play.

What the heck the network layer has anything to do with the db one ?
Katie:
If I synchronize all methods on Data would I be safe?

You have *one* Data instance per client / *thread*. How any synchronization on your Data instances could help ? Your clients/threads currently have an *exclusive access* to their own Data already.
---
It looks like Katie has one RAF instance per Data instance and one Data instance per client. So there is no possible multithreading issue with her design. What I am a bit unsure about though is how multiple RAF instances accessing the same physical file really behave. Dirty reads issues are obvious, but as I didn't *test* such a design, I am unsure about other possible issues. Jim is a RAF specialist (among many other specialties ) so I hope he'll read us and reply.
Now Katie, if I were you, I'd write a small test of multiple RAF instances owned by multiple threads and accessing the same file concurrently with reads and writes, just to see what happens...
Best,
Phil.
 
Katie Kelly
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bharat and Phil,
I was originally assuming that if each client has its own instance of RAF add each RAF instance has its own file pointer, then there is no way that two objects can alter the position of the file pointer. I think I'll try the test to see how the RAF behaves.
Thanks!
Katie
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Katie,
Your assumptions are OK IMO : each of your RAF instance will have *for sure* its own file pointer (BTW they don't even know that they are not unique ). But, besides the "dirty reads" issue pointed above, how do multiple RAF instances concurrently playing with the same file behave when the file size changes, for instance ?
Looking forward your test results !
Best,
Phil.
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Philippe Maquet:
Hi Katie,
But, besides the "dirty reads" issue pointed above, how do multiple RAF instances concurrently playing with the same file behave when the file size changes, for instance ?
Looking forward your test results !
Best,
Phil.

Very badly, I'm afraid. However, depending on the version and generation of the assignment, this might not be an issue that needs to be addressed.
Btw,
Phil, when the heck are you going to add SCJD to your signature? You're more then ready.
All best,
M
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Phil,
No, I am not trying to be naughty and purposely confuse the issue. Thing is: I went through the same thought process that Katie is going through and was helped along the way by a lot of people including you. Merely trying to do my civil service.
Katie & Phil
Having multiple instances of the Data class use one instance of the file-pointer each, i.e., each Data class instance instantiating its own file-pointer instance is definitely a bad idea. Think about it; first the operating system may or may not allow many file pointers rovng about within the same physical file and safeguard the integrity of the data at the same time. Even if it did, how many instances of the file-pointer can you open at the same time? Isn't it platform dependent? I do believe that one of the goals of the assignment is to program in a platform independent way.
Katie, What I did is to define another class DataSchema as a singleton and besides making it responsible for managing the file header information, it also instantiated a file-pointer instance for me. Since DataSchema is a Singleton and it instantiates the file-pointer, multiple instances of the Data class can share the same instance of DataSchema class and in turn, a single file-pointer.
Once you buy into the point that you have a single file-pointer doing read/write on a single physical data file, you need to synchronize access to it.
Katie, you can synchronize the methods of the data class doing read and write on the file and be sure that the file pointer will not be moved unexpectedly, but that is a lot of unnecessary overhead. Since you will be doing other things besides just reading and writing within those methods. Keep in mind that your synchronization blocks should be a) as explicit as possible to maintain clarity, and b) as small as possible to keep the clients from waiting any more than they should. I found that if I synschronized around the file-pointer before doing read/write from the file, the code became more or less self-documenting and as efficient as possible.
Lastly, Phil, in RMI you are not guaranteed that the same thread with stay with the same instance of the Data class for its entire life or even for the duration of a method completion. The RMI engine will switch threads in and out according to its own algorithms, therefore synchronization around the single file pointer becomes an important issue. May be you and I were disconnecting because I assumed that Katie will be using a single file pointer instead of multiple file pointer. Actually, Jim had explained this point in detail in an earlier thread a while ago.
Best of luck to you both.
Regards.
Bharat
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Max !
Nice to see you back !
Btw,
Phil, when the heck are you going to add SCJD to your signature? You're more then ready.

Thanks for the "readiness". It's now a question of time and new priorities. I suspended my SCJD assignment about 6 weeks ago for short-term professional reasons. But after my J2EE certs (I'd like the next one to be the SCWCD beta), I'll finish my SCJD assignment.
Best regards,
Phil.
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bharat,
No, I am not trying to be naughty and purposely confuse the issue. Thing is: I went through the same thought process that Katie is going through and was helped along the way by a lot of people including you. Merely trying to do my civil service.


Katie, What I did is to define another class DataSchema as a singleton and besides making it responsible for managing the file header information, it also instantiated a file-pointer instance for me. Since DataSchema is a Singleton and it instantiates the file-pointer, multiple instances of the Data class can share the same instance of DataSchema class and in turn, a single file-pointer.
Once you buy into the point that you have a single file-pointer doing read/write on a single physical data file, you need to synchronize access to it.

Sounds reasonable.
Katie, you can synchronize the methods of the data class doing read and write on the file and be sure that the file pointer will not be moved unexpectedly, but that is a lot of unnecessary overhead.

Not only unnecessary overhead, but a non-sense (Katie's Data instances are *multiple*).
Lastly, Phil, in RMI you are not guaranteed that the same thread with stay with the same instance of the Data class for its entire life

Agreed, and that's the same in my sockets implementation. But where does it relate to the issue of synchronizing or not the file access ?
or even for the duration of a method completion.

Where did you read that ? Do you *really* think a Java method can start in a thread/call stack and later complete in another thread/call stack ?
Best,
Phil.
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Phil,
You wrote:

But where does it relate to the issue of synchronizing or not the file access ?

Well, if the RMI system decides to suspend the execution of a Data class instance temporarily and time slices another thread for execution that also has file pointer movement related instruction then we are going from the middle of writing may be half a record in a write method to reading another record in another part of the file. This is, off course assuming that you agree that only ONE instance of the RAF file pointer is used for reading/writing all records as both Max and I explain above?
You wrote:

Do you *really* think a Java method can start in a thread/call stack and later complete in another thread/call stack ?

We may not be communicating again. Let us put this in the proper context. Suppose we have a java method called method1 on object O1 which is user-defined, i.e., somebody wrote it for a particular purpose. Unless the method is declared as synchronized, my understanding is that the operating system (or the RMI sub-system) is free to suspend the execution of the method and use the thread to execute another object's method and slice back to where it left off based on whims of the scheduler. If the method is marked synchronized however, then only one thread can access it at a time. A synchronized block is a mini-method within a method for the purpose of serializing the thread access in my book so I don't see any real divergence there. That is what I meant when I wrote the above sentence. Actually, all of this is quite well explained and much better articulated in Max's book. Speaking of which, Katie, I am not sure if you have Max's book. Highly recommended.
Regards.
Bharat
 
Peter Yunguang Qiu
Ranch Hand
Posts: 99
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Excuse me.
Could I ask a "greenhorn" question?
What are singletone and multition?
Peter
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bharat,
First about the main subject, the RAF. We *agree* on that. Katie has/had one RAF instance per client, so she couldn't get any multithreading issue at the RAF *instance* level. *BUT*, I wondered what whould happen at the *file* level. Dirty reads are one thing, but I was a bit afraid about what could happen when the file size changes (see my post above Max's one) : hence the tests I suggested. Your solution is correct : one RAF instance *shared* by all clients. And in this case of course, access to it must be synchronized.
The only thing on which we still disagree is what you wrote above and repeated just above : "the operating system (or the RMI sub-system) is free to suspend the execution of the method and use the thread to execute another object's method and slice back to where it left off based on whims of the scheduler."
No ! It's im-po-ssi-ble. The *thread* running method1 will be suspended and time slicing will give a chance to *another* thread to run. Remember that each thread has its own private stack and that stacks are never "mixed".
Best,
Phil.
[ December 30, 2003: Message edited by: Philippe Maquet ]
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Peter,
Singleton and Multiton both are design patterns.
Singleton ensures that a class will never been instantiated more than once.
Multiton is similar in the sense it will limit the number of instances created based on some characteristic of the instances (ex. the db file name of a Data class : if Data is a Multiton based on the file name, you'll never have more than one Data instance per physical file).
I've put two links to documents on design patterns in this thread.
Best,
Phil.
[ December 30, 2003: Message edited by: Philippe Maquet ]
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Phil,
You wrote:

No ! It's im-po-ssi-ble. The *thread* running method1 will be suspended and time slicing will give a chance to *another* thread to run. Remember that each thread has its own private stack and that stack are never "mixed".

Good point! I stand corrected.
Regards.
Bharat
 
Katie Kelly
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bharat,
I think I understand what you are getting at now. Is the idea that you are managing a single variable (I guess it would be a long) that is shared among all instances of Data and is used for calls to seek() on the RAF? So, you synchronize on that variable when you do reads and writes? I guess that this really amounts to allowing only one instance of Data to operate on the file at a time. Is that correct?
Thanks!
Katie
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Katie,
Yes, I am managing a single "instance" variable in the Data class that comes from the DataSchema class which is defined as a singleton. The type of this variable is RandomAccessFile and not long. Yes, you do call seek on this variable.
You wrote:

I guess that this really amounts to allowing only one instance of Data to operate on the file at a time. Is that correct?

That is the net effect. Correct.
Regards.
Bharat
 
Peter Yunguang Qiu
Ranch Hand
Posts: 99
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Phil, I have downloaded the books
Peter
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic