This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I added similar method to my custom interface (which extends the given interface). I added a shutdown hook which calls this shutdown-method. And for my server I have a small gui with some input fields (for configuration settings) and a start and stop button. But that's not required, just showing a popup to enter configuration settings is fine according to instructions.
How you let the user stop the server is up to you: small gui like me, Ctrl+C, typing "shutdown",... are all ok (because you have a user guide which explains the process).
I reused the configuration settings panel in my server gui
I know Roberto Perillo used a dialog for entering the configuration settings and then started the server without any gui. So you just see the console window with maybe a user message like "Server is running... Press Ctrl+C to stop server."
Using pure console for the server will definitely save time (especially for those of us with extremely limited time and still want to make the 31st July deadline). But mistakenly closing the console hosting our server will automatically close the server without the "Do you really want to exit?" message. Doesn't really sound so nice to me; or what do you think?
Cathal Mullan wrote:
I am planning on extending the DB interface by another interface & add a shutdown() method. This method will close my DB's RandomAccessFile & it will be a synchronized method.
Why do you make that method synchronized? It will either be called by the stand-alone client thread or by the server thread. And it will only be called once (on exit).
Maybe I make a mistake here. I implemented all access via the RandomAccessFile in a non-synchonized way. The caller starts the database and the records are read and the closer will cause the database to write the records back to file and close.
SCJP, SCWCD, SCJD
Joined: May 20, 2011
I'm going to do all my thread synchronisation in my Data class. Any methods modifying the DB file or locks will be synchronised.
The shutdown() method will be synchronised because if a thread is writing to a record & another thread shuts down the DB file at the same time I will get IOExceptions for trying to write to a closed file.
Wondering if any1 who passed the OCJD did it this way also?
Dennis Grimbergen wrote:Why do you make that method synchronized?
My guess would be to make your Data class thread-safe
Dennis Grimbergen wrote:Maybe I make a mistake here. I implemented all access via the RandomAccessFile in a non-synchonized way.
And how did you make sure your Data class is able to handle multiple concurrent request by different clients?
I imagine you have following pseudo-code (and both methods will work on a shared instance of RandomAccessFile):
// 1. position file pointer at the correct position to read the given record number
// 2. read record (bytes)
// 3. turn bytes into String
// 1. turn String into bytes
// 2. position file pointer at the correct position to update the given record number
// 3. write record (bytes)
Let's imagine the following little story about 2 clients: ClientA wants to update record 1 and ClientB wants to read record 2. ClientA (represented by Thread-15) enters the update-method, executes the 1st and 2nd step. So the file pointer points to the location of record 1 at this moment, ready to write the new content. But unfortunately the thread scheduler makes a harsh decision: Thread-15 has to go back to running state, because Thread-23 (the representative of ClientB) gets a bit of CPU-time. So Thread-23 enters the read-method and executes the 1st step (the file pointer now points to location of record 2). The thread scheduler realizes he was a bit harsh a few moments ago and decides to give the CPU-time back to Thread-15 (and Thread-23 goes back to the running state). Thread-15 starts where it was left before going to running state and executes step 3. So it updates record 2 instead of record 1 (because the file pointer was moved by another thread). The end!
Back on the shutdown() question, I decided to close the data file after
each transaction, in a finally block. This keeps things very reliable and
simple. As data volumes are low, and mostly GUI driven, this seemed
efficient enough. So shutdown became a non-issue. Just exit(1) the