I'm using RandomAccessFile for IO. Is it best to have one instance of RandomAccessFile? Or to create a new RAF object in each method? Also, let's say you are in the middle of the file. How do you move the file pointer back to the beginning? Do you have to mark the beginning of the file using getFilePointer() and then seek to that position?
I suppose this all has to do with how you are implementing your business methods. If you are synchronizing your access to the file, then only one RAF is needed. However, if you are concurrently allowing clients to alter the database, relying only on locking/unlocking records for synchronization, then multiple RAFs will be needed. (Because with only one RAF, there will only be one position pointer for where it is reading/writing). I implemented mine with a new RAF for each business invocation. However, I'm sure there are other solutions. Just make sure it's justified somewhere for your grader. As for moving the file pointer, look it up in the API docs. You'll find the seek(int) function, which seeks to a position (>= 0) in the file. Easy to get around and do stuff. You'll need the getFilePointer() function if you need to go backwards, since skipBytes(int) won't accept a negatitive number (well, it will - but won't do anything). So, you'll have to use getFilePointer() - (# bytes to go back) and set that with seek(). Pretty simple stuff once you have to start using it everywhere in your data access object. Hope this helps.
I have a similar question: I am using RMI, does it mean that there is only one client can read/write the file at one time? if it is, so why should I need lock/unlock?
Hello Guys, I think I can answer this question with some degree of confidence. However, my approach may not be the only correct one. I had used a design where there was one instance of the Data class created for each RMI client. To keep the clients from stepping on each-other, I implemented the lock, unlock, and islocked methods provided in the DBMain interface (I did the URLy Bird assignment, but it applies equally to the Contractors assignment as well). This is known as logical locking. Using the aforementioned three methods and a static data structure such as the WeakHashMap, you can implement the logical record locking. In addition to the logical record locking, you need to make sure that the record pointer which does read/write operations on the RAF is not moved in the middle of an operation. Keeping multiple file-pointers is a bad idea from scalability point of view and there are operating system constraints on how many of these can you have open concurrently in the first place. Also, I am not sure if the RAF is designed to support multiple file pointers accessing different portions of the physical data file concurrently and performing different operations. So regardless of the fact that you are using a design that has multiple instances of the Data class accessing the same physical file or a single instance of the data class accessing the physical file, you need to make sure that the same file pointer is used to perform actual physical read/write operations. This means that you need to open only ONE instance of the RAF file-pointer and share it amongst the multiple instances of the Data class. I had a singleton class called DataSchema that managed creation of the file pointer. Another thing that you need to think about after you buy the point that only a single instance of the file-pointer be used is how do you stop the file-pointer to be repositioned in the middle of a read/write operation. This is where synchronization comes in. I synchronized on the single instance of the file-pointer class that I used whenever I did read/write. Yet another thing that you can do is read/write the entire record in one operation. Typically, this is done using byte-arrays though there may be other methods. Also, look into the ReadFully method of the RAF which is designed to not only read the entire byte array but also block the I/O while it is doing that. If you need any more explanation on this, please do a search on my name "Bharat" and go through the threads that I participated in while developing this solution with plenty of help from others on the forum. Hope this helps and you all are asking the right quesitons. Regards. Bharat
This class has a single public method that is also static, which will keep returning the same instance no matter how many times the static method is called. This means that there is only one instance of this class that is instantiated. This is known as Singleton. There are many slight variations of this, but basically the pattern is the same. Hide the constructor, and access the sole instance via a public static method. Start using google on a regular basis. It finds a wealth of information out there in split seconds. Regards. Bharat
Personally, whenever I needed to read/write from the database file, I used RandomAccessFile. I only had one instance of the RAF, and always referred to it when I needed to read/write from the file. In order to find a position in the file, you use seek(int filePtrPosition). This will let you get to the specific position in the file you need. What I did to read/write records from the file was just know where the records begin, and then offset the number of bytes that the record was. Seemed too simple, but it works. Zak SCJP 1.4
Originally posted by Bharat Ruparel: ... protected Singleton()...
Although, strictly speaking, the GoF definition of Singleton's constructor has private access, I would not use protected or private for the constructor for purposes of the SCJD project. My reason is that Sun's testing regime might try to do something with the singleton class that the private constructor would thwart. Why push your luck? Although if someone got a perfect score and knows that they used pricate no-arg constructors, it would be interesting to hear from them now.
Although, strictly speaking, the GoF definition of Singleton's constructor has private access, I would not use protected or private for the constructor for purposes of the SCJD project.
I did, and got full-points. Hello Joe, Your code should synchronize around the RAF Pointer instead of "this" as follows:
Let's say my read() method is synchronized around the RAF pointer, and then I use this method within my find() method which is also synchronized around the RAF pointer. Is it ok for them both to be synchronized around the same thing?
Good question! As long as your read() method doesn't call the find() method before it exits the RAF synchronized block (or vice versa, the find() method calling the read() method), you are OK. The key is that you shouldn't have a synchronized block nesting another synchronized block. It is OK for both the methods to be synchronized around the same RAF pointer if you follow what I explained above. Hope this helps. Regards. Bharat
Post by:autobot
It sure was nice of your sister to lend us her car. Let's show our appreciation by sharing this tiny ad:
a bit of art, as a gift, that will fit in a stocking