Andrew said
While you should always try to avoid nested synchronization, sometimes it is not possible to avoid it totally. As long as you always nest in the same order you should be OK.
I guess we need 1) to determine what objects need to be accessed in a multi-thread safe fashion; 2) and then determine how it can be achieved.
That is what I've got so far:
1. For the logical locking (ie record locking) there is a static
lockedRecords map that stores key/value pairs where the key is a record number and a value is a client who has locked it
2. For the physical locking (ie file locking) there is a static
dbFile object that provides read/write access to the database file (it delegates read/write tasks to the instance of RAF)
3. For the record cache there is static
recValidFlags list in which an element position represents a record number and the actual element is a record validity flag (of byte type, either
Data.VALID_RECORD or
Data. DELETED_RECORD). The actual number of elements in this list represents a total number of records in the file (both deleted and valid).
recValidFlags is initially populated on the start up (when the database file is chosen by the user) and is then maintained by the
Data instances.
Collections.synchronizedList(new ArrayList<Byte>()) method is used to create a
List instance used for this cache, which makes access to
recValidFlags methods multi-thread safe.
The
recValidFlags cache is used for a) checking whether the record exist; b) determining in what position to create a new record.
The
recValidFlags cache is modified when a) a new record is created ; b) when a record is deleted
Data instances will synchronize on these three static objects ( ie
lockedRecords /
dbFile /
recValidFlags ) in the following manner:
Data#read(int recNo) Data#create(String[] record) Data#lock(int recNo) Data#delete(int recNo) All comments are welcome.
[ December 19, 2005: Message edited by: Alex Sharkoff ]