Kalichar,
the locking is implemented in the Data class via modification. I did not add an additional layer although I now think I should have done so. It makes the whole thing clearer.
I have one Data instance per DB-File which is shared amongst all clients using this particular file. The Data class implements a DataInterface interface which extracts the public interface of the Data manipulation methods.
Each client has a DataProxy instance on the client side that implemets the same DataInterface so that the client does not need to know whether it is dealing with a local or remote DB file.
The DataProxy itself is connected to a server side DataSession instance. This DataSession belongs to one single DataProxy and has a reference to the shared Data instance and performs the real work using this Data instance.
The Data class has the following lock method:
public void lock(Object session, int record)
This method puts the lock into a hashmap where the key is an Integer with the record id and the value is the session object. It checks for an existing record or DB lock before, of course.
For multi-user mode the client executes the lock(int record) method on the local DataProxy which executes lock(int record) on the remote DataSession which in turn executes lock(Object session, int record) on the shared Data instance. The DataSession passes itself a the session parameter to the lock method. For single user mode the client directly executes the method lock(int record) on the Data instance which does nothing but call lock(Object session, int record) with a
String constant as the session object.
That way the DataSession holding any lock can be identified and vice versa. That means that as soon as the DGC collects the DataSession of a dead client you are able to remove the associated locks.
I synchronized on the Data instance, so notify() always wakes up all threads waiting for a lock, no matter what lock it is. I did not implement a lock queue either.
From what I can see this is a perfect fit. Not too easy, not too complex (it is mentioned in my assignment description that it should be understandable by junior programmers).
Good luck!
Rainer