For the same reason that Data is not. If you can have multiple Data objects representing different tables then you must have a different LockManager for each table. So making LockManager a singleton causes the same maintainance problem as making Data a singleton.
1. Whether I should implement the wait() and notifyAll() in the LockManager?
My consideration is that if we implement them in RemoteData class, we need to change the lock() method's signature to synchronized, that's not i wanted.
2. Is my implementation for lock and unlock, especially for database lock corrcet? PLS comment.
So I plan to write some class named LockManagerFactory to create singleton LockManager for each Data instance. Is that necessary?
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
My reasoning was that since my remote connection had references to both Data and LockManager, there was no need for Data to participate or even know there was such a thing as a LockManager or remote connection object.
In my implementation the remote connection object "played nice" by verifying it actually had the lock before performing a volatile operation on Data (ie modify(), etc.).
I don't really understand why you think it is necessary to call wait() and notifAll() on Data. You may have a good reason. If so please explain.
Also, you have a potential dead lock situation when you release the lock.
There is certainly nothing wrong with that approach. I used a builder pattern and kept a static protected map of LockManagers in my DataBuilder class. Actually, I think your way is more elegant. If you are using a DataFactory similar to what I did, you could even create the LockManager at the first request of a client for each Data object. You could have a method like LockManager getLockManager(Data data) in the DataFactory.
1)Local Data - Allow user specify directory and filename of data file.
2)Remote Data - Allow user specify address of remote server and port on which it is sering the data.
Is that the way you mean "there was no need for Data to participate or even know there was such a thing as a LockManager"?
I'm not so clear about your mean "verifying it actually had the lock before performing a volatile operation on Data", can you give some details for that?
I really want to call wait() and notifyAll() on the LockManager itself, but aftering seeing so many person call the wait() and notifyAll() in the Data class, I just lost my confidence. So thanks for your explanation.
And as my code looks so simple(compared to other one's implementation), I kept wandering whether I lost something important or necessary, such as the priority between the database lock and record level lock, and so on. Any comment about that?
According to my understanding to the relationship between RemoteData, Data and LockManager, my implementation for RemoteData just as following:
...
Any comment for above code?
If above point is right, then the ConnectionFactory(which just create RemoteData instance) should use the default path for the server side db.db, is that right? For when the client call a getConnection() method from ConnectionFactory, no path information will get, and ConnectionFactory still need to construct the RemoteData with exact dbname.
If my above understanding is not right, how about your implementation? Thanks.
Ok, having asked so many questions, there is only one left. It's about the switch between local mode and remote mode. In order to encapsulate the details for switch and make use of the DataInterface, I write some method getData(String command) to get the right instance. Any suggestions for above implementation? Anyone has the similar consideration?
So sorry for asking so many questions, but they have badgered me so much time. I just hope I can get the help from you!
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
The path could also be selected after boot from the server GUI File menu. The client doesn't need to know where the physical location of the database file on a server.
The local connection object did not have a reference to a LockManager and the lock() and unlock() methods were empty. It also did not check the lock status before a modify(), it just modified.
I'm not suggesting that you do it this way but I would like to see some more details of how you want to create the two different connections.
"The path could also be selected after boot from the server GUI File menu." Is this path only for the client mode?
Yep. My code is just similar with your idea. But now I just use Data directly for local mode. I'm not so clear about why we need such a local connection object?
Now I'm going to see some topics about Build Pattern implementation. Maybe later I can give more details in code.
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
At server startup the actual database server was not running in my implementation. There was a button on the server GUI to start the database server. Before pressing that button, the user could select a different database file from the one entered on the command line. My database server could be stopped and started any number of times as could the database file be changed.
I did not provide a means in the client to change the database file, although I did consider it. My client was also "one-shot", ie once the data connection was closed there was no way of restarting it.
Don't change your overall design just to use the Builder Pattern. It sounds like you have a handle on everything already.
I don't quite get why you want to check whether isRecordLocked(record.intValue(),this) is true or false. In the doBooking(int,int) method, we always call lock, read, modify and unlock in sequence... I assume that isRecordLocked(int, Object) will always return a true before modify(DataInfo) call and after lock(int) call, which means it is redudant(?).
Also, I noticed that the wait() call in lock(int, Object) is not in a loop(while) in some posts and Nate said wait() should be in "if". I am confused now. Ken Arnold in his book: The Java Programming Language Third Edition says that wait() should always be in a loop (page 244).
Up to now, My LockManager doesn't function like a singleton and still has a problem to lock a record. I started ten threads and each thread book a one ticket on same record ten times, so it is 100 tickets, but the total seats did not reduce 100... Somethings are wrong... I will look other posts about the testing lock...
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
<Michael Morris>
Actually I kept a HashSet of locked records, nothing to map them to.
</Michael Morris>
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
while (dblock || isRecordRegistered(record)) {
wait();
}
hm.put(new Integer(record), data);
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
Even crazy and silly looking problems are sometimes real.
all that says that i can remove the lock and unlock method out of the data class and provide it only in my remote interface and remote impl ... am i assuming right or making a ass out of myself here
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
I hit a big bump. My lock implementation behaves like database lock, not a record lock. At any moment, the size of HashMap in LockManager is either 1 or 0, never exceeds 1 though a lot of threads tried to book different flights. The doBooking(int,int)[including lock,read,modify and unlock] is synchronize, otherwise, it hanged and deadlocked....
what is my problem? could you give me some hints?
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
roses are red, violets are blue. Some poems rhyme and some are a tiny ad:
New web page for Paul's Rocket Mass Heaters movies
https://coderanch.com/t/785239/web-page-Paul-Rocket-Mass
|