Hehe, taalgenoot
Ok, what I understand from your story is that you are using read/write locking on logical level. that gives you this:
- multiple reads, as long as no write lock is given
- when a write lock is given, all other reads must wait
- when a write lock is given, all other writes are appended to the queue
So, you do not have multiple writes, only multiple reads when there is no writing going on...
In that case you *won't* need physical locking. The only thing you have to do is make sure that no multiple reads use the same RAF, so you create a pool of RAF's . This way every read occurs at the same time on a different RAF. The fact of having x number of RAF objects is no performance issue because creating a RAF instance is a very low cost (check the code for yourself) .
Note: the RAF pool was a sugesting made by Monk House on a question of mine. He also sugested to make sure that the underlying OS supports the handling of more then one RAF on the same file handle. So you could make this check first in your code and depending on the result create a pool varying from 1 RAF to x RAF's.
Now, with this system (read/write locking) keep this deadlock scenario in mind:
- Thread A wants to update record 1. It gives his version of record 1 + the updated version of record 1 which should go in the database.
- Thread A obtains write lock for record 1
- Thread A does a read, to see if the version thread A has of record 1 is still valid (making sure that it has not been changed in the mean time)
Since record one is allready locked for writing, the read cannot occur, and you have a deadlock. You could ofcourse make some bypass code, but I don't think thats the way to go.
I would solve the locking fairly simple:
Just implement a queue based write locking on logical level, and syncrhonize on the read/write methods as physical locking level. This way you:
- do not have multiple writes because of the queue
- you have the use no cpu cycle thing from the assignment covered when using a queue
- still can do reads after you put a logical lock on the record
- no reads can occur while the actual write takes place->due to syncrhonized
- no writes can occur when reads are taking place->due to syncrhonized
I think this solves about all the possible locking problems.
There are downsides of this solution, but all of them are performance wise. For example: you cannot do multiple reads at the same time, because of syncrhonized.
So the solution using read/write locking and no physical locking will perform better. But the assignment does not talk about performance ...
Suggestions about this are more then welcome