Reputation: 11
I would like to cache some IO with the help of ConcurrentHashMap
. The modification on the binary file should be reflected in cache as well. Since the cache is going to be used by multiple threads all IO operations are synchronized. Modifications of map go inside the same synchronized
block. Which roughly looks like:
synchronized (file) {
file.deleteRecord(index)
map.remove(index);
}
and
synchronized(file) {
file.writeRecord(index, record);
map.put(index, record);
}
Both map
and file
are private and are not seen from outside the cache-class.
Is thread-safety preserved if cache reads, namely map.get(index)
, go without the synchronized
block?
As I mentioned earlier, ConcurrentHashMap
is used as map implementation.
Upvotes: 1
Views: 3946
Reputation: 4706
Well, as everyone here says, this is thread-safe in that you have a happens-before relationship between the write to the cache and the read from the cache, but that may be meaningless depending on what other guarantees you are hoping for.
For instance, unless you fsync the file there's no guarantee the record will be written to disk, so you may not read the record from disk (depending on the file-system and a few other factors). There is also no happens-before relationship between the writeRecord/deleteRecord and map write and the read from the map, so the JMM doesn't guarantee that you read something from the map that has definitely been written to the file.
You do get a guarantee that the state of the index
and record
objects as written will be what will be read, although if either of these are mutable then that may be a fairly useless guarantee.
Upvotes: 0
Reputation: 589
Yes, ConcurrentHashMap is thread safe, so reading (or writing) does not require any locking on your part.
However, in your example, you might end up with the following sequence of events:
file.deleteRecord(index);
map.get(index) // returns the mapping for index even though it has been deleted from file
map.remove(index);
(the same for writeRecord/put). This might or might not be a problem in your case.
Upvotes: 1
Reputation: 38878
Yes, thread safety is preserved down to the map references, thanks to the ConcurrentHashMap implementation.
The objects you store in the map are another story.
Upvotes: 2
Reputation: 1501043
Yup. This is basically the point of ConcurrentHashMap
. From the documentation:
Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset.
and from the package documentation:
A concurrent collection is thread-safe, but not governed by a single exclusion lock. In the particular case of
ConcurrentHashMap
, it safely permits any number of concurrent reads as well as a tunable number of concurrent writes.
(Both of those documentation pages have much more detail, of course. They're worth reading carefully.)
Upvotes: 5