Jianhua Ren

Greenhorn
+ Follow
since Oct 19, 2003
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Jianhua Ren

I think Miguel means that when you especially select one row, his program will check the seats availability for that entry, if no seats are available, book button is disabled; if seats are available, book button are enabled.
Miguel wrote:

I've made like this and if the available seats where 0 the book seat button was disabled for that specific row in the JTable


Regards,
Jianhua
[ December 11, 2003: Message edited by: Jianhua Ren ]
Thank you Andrew!
I think I have to make these two static variables private. It means they can be accessed only through getter method and their value is shared among all objects of the class.
Regards,
Jianhua
Andrew,
Thank you for reviewing my design. I really appreciate your time!
I revised something based on your message. Actually I want new object returned to client, so

By doing so, I have to change my server class, since I only want one instance of Data class shared by all server objects. Without doing singleton, I think I can simply declare static variable:

How do you think about this revised version?
Thanks,
Jianhua
Thank you for reply, Andrew, Philippe!
Right now, I came up with a picture like this:
--- server side-----

Andrew, how do you think this whole picture? it's going to work and pass the exam?
Looking forward to your reply!
Thanks,
Jianhua
[ December 04, 2003: Message edited by: Jianhua Ren ]
[ December 04, 2003: Message edited by: Jianhua Ren ]
Me again, let's put this in another way. Assuming I implement lock/process/unlock logic inside my remote database server class, what I should do for booking() method in client side? since in the future the database might be designed for other purpose not for travel agent, business specific methods should not reside in the server side, so I choose to implement booing() method in client side. Problem is booking method involves several database operations, lock/read/modify/write/unlock, but remote database server's modify(), and write() already contain lock/process/unlock logic, I don't want to lock twice(one is in client side, one is in server side), it's not going to work! I am really confused here! Could anybody help me out?
Thanks a lot!
Jianhua
Hi,
I am working on Fly by Night assignment. Spec askes me to expose all public methods of Data class to client. Due to this requirement, I think we should implement thread safe behavior such as lock/doingSomething/unlock for the database server in client side and only add book() method in client side. By doing so, the remote database server just delegates the requests to the Data class.
However, spec also asked me to do the following:
Because multiple concurrent connections may exist, you must make both your server and the suncertify.db classes threadsafe.
Since right now, I rely on the client side to guanrantee the thread safe for database server(call lock before call database modification methods), it seems the database server itself is not thread safe, because I don't have lock/process/unlock this kind of style code inside the database server class. It sounds like there is confliction of these two requirments here.
Any suggestions?
Thanks a lot!
Jianhua
Philippe, thank you very much for your comments.

Are you sure your lock() method may throw an IOException ?


Yes, lock() in my assignment does throw IOException, I am working on FBNS.

Your first call to validateRecord() is useless IMO. Think of the fact that if the record is invalid, nobody will have a lock on it, in such a way that you won't wait for it.
Your second call to validateRecord() should go out of the while loop (just before lockedRecords.add()) : your goal is not to validate the record each time you get a chance to grab the lock, but when you actually can do it.


You are right. Actually I already took off the first call to validateRecord(), and moved the second call outside the while loop already. You may just overlooked that message I posted in the middle part of this thread. But, still want to thank you for pointing that out.

I see a big issue with the way you get a database lock : let's say that T1 owns a db lock and T2 and T3 are waiting for such a db lock. When T1 will release its db lock, T2 *AND* T3 will be granted the db lock. You should replace the if(dbLockRequest) by a while(dbLockRequest).


This is my fault. Yes, I have to change it to the while loop. What a comment it is!! Thanks again, Philippe!!
Andrew,
Thank you very much for your comment!!
I will take care of the variable name issue.

Also, you have a requirement that only the client that locks a record may unlock it. How are you handling that? (I suspect that you are handling it the same way I handled it (and therefore I think you are right ) - but I just want to check that you have not forgotten about that requirement).


Yes, I am not forgetting that. I think I will handle it the way you did. Keeping track the info of clients and records which they lock outside the Data class, only when the client which locks the record comes, the unlock call will be forwarded to Data class's unlock without changing the signature of unlock() of Data class.
Thanks,
Jianhua


But T1 will wait at the POINT X, becos, by refering to T2, T2 enters the critical section, so T1 cannot enter into it.


I finally knows what you're thinking. But one thing you should notice is that wait method does release the lock, it's different with sleep method and yield method(sleep and yiele still holds lock while it sleeps or yields).
So T1 will not wait at the POINT X, it will get into the synchronized block of unlock method, since before T2 waits, it releases the lock of collection of locker first due to calling of wait method.
You can check the Max's book on page 81/82, he explains the wait method and gives the example.
Hope this helps!
Jianhua


However, if we synchronized locker in lock(), even if other thread wanna release their lock, they cannot do so becos it is hold by the current thread. Am I correct?


The case you mentioned would not happen.
The lock we think is that the record number is contained in the collection of lockedRecords, we say Thread 1 holds the lock of record 1, that means "1" is contained in the collection, so as long as Thread 1 still holds the lock of record 1("1" is not removed from collection), other threads cannot hold that lock of record 1, since the while loop will make them to wait.
If Thread 1 wants to release it's lock on record 1, it must mean that collection of lockedRecords contains "1" at that moment, since lock/operation/unlock logic has to be followed. So when other threads which want to do sth on record 1 come, they have to call their lock method first, they will find that "1" is in the collection already, then they have to sit there waiting, only after Thread 1 finishes it's work on record, removes "1" from collection of lockedRecords, the waiting threads for record 1 would be notified, then go to compete for the lock of record 1.
Make sense?
Jianhua
Do you agree that every database operation has to follow the sequence lock/operation/unlock? If you agree, let's take a example step by step:
1. Collection of lockedRecords is empty
2. Thread T1 which wants to delete record 1 comes
3. T1's lock method gets called, lockedRecords contains one element representing record 1
4. At this moment, thread T2 which also wants to do something on record 1 comes
5. T2's lock method gets called, it checks the while condition("if Collection Contains 1"), it finds record 1 gets locked, then it goes into wait status
6. Thread T1 deletes the record 1 in the database, removes "1" from the lockedRecords(collection of lockedRecords is empty), and notifies other threads which wait for record 1 locks.
7. Thread T2 wakes up due to the notification from T1, checks the while condition("if Collection Contains 1"), condition is not satisfied, jumps out from the while loop
8. validates existence of the record 1, exception is thrown from validation method, since record1 does not exist.
9. collection is empty after all these steps.

How do you think?
Jianhua
Nick,

Even if the current thread checks again the validity of a record after it's wait() and before it's lock(), other thread can remove it in the mean time.


How other thread can remove it after you got the lock of that record? If other thread's still working on that record, you cannot get the lock of that record. Once you get the lock of that record, it means no other threads are working on that record(lock of that record must has been released already). No need to synchronize the RAF.
Jianhua
Hi Nick,
Thanks for checking this! I think you're right, I have to take off my first validation method and move my second validation method outside the while loop, just before lockRecords.add() method. By doing so, assuming thread A is holding the lock and trying to delete the record 1, thread B which wants to modify record 1 comes, thread B will wait until thread A finishes its work, releasees the lock, thread B gets the lock, at this moment no any thread is working on record 1, so we can put validation of record 1 method here. How do you think about this, Nick?
Thanks,
Jianhua
Andrew,

The if statement in the following code appears redundant. Why do you have both an if statement and a while statement that are doing the same check?


After I reconsider my code, I made a modification on my lock method, it looks like the following, no duplicate checking there now:

1. Regarding the validation of record. I think we have to put the validation in the two places, one place is in the very begining of the lock method, if the record is invalid, no need to do futher work at all; another place is just after waiting thread gets mutex lock, because maybe the record in which the waiting thread is intrested has been deleted already by another thread while the waiting thread was in the wait status.
2. Regarding the lock whole database. I used a static variable DB_LOCK_REQUEST to monitor the database lock request and actual database lock action, no new lock is allowed once the database lock request is monitored(threads with new lock request have to sit there waiting), after all existing locks finish the lock action and unlock the locks, the database got locked; DB_LOCK_REQUEST will be disabled in the unlock method, then all the waiting threads will be notified. If a new database lock request is monitored while there is existing data base lock request there, the thread with new database lock request has to wait. I just added the new piece of code above to handle this case.
Any comments? I am missing sth here?
Thanks,
Jianhua
I think I know the answer now. Since in DVDAdapter class, each method calls reserveDVD()(same to our lock() method) first, it guanrantees thread safety, no need to synchronize the mothod. Correct me if I am wrong.
Thanks,
Jianhua
In Max's DVD example, an instance of DVDDatabaseImpl is registered in the registry, so the reference of that instance could be used by multi request threads. But why the methods inside DVDDatabaseImpl such as rent(), returnRental() are not synchronized?
DVDDatabaseImpl contains one instance of DVDAdapter, same thing, methods inside DVDAdapter are not synchronized. I think the methods should be synchronized either inside DVDDatabaseImpl or inside DVDAdapter, am I wrong or right?
Thanks,
Jianhua