Reputation: 9031
I have reference data stored in a class using multiple hash maps
Map map1;
Map map2;
Map map3;
They are accessed concurrently by multiple readers. I want to re-initialize them all at the same time. If it were a single map, i could just do
public void reload(){
map1 = createNewMapWithLatestData();
}
Since the existing readers have the old reference and the new readers get the new reference it works fine. But since I have multiple maps it is possible that new readers could get latest version of say map1
and map2
but an older version of map3
, since the replace operation is not atomic.
Ok, so I need to lock this down, which brings me to my question. Other than locking down everything using a synchronized
, what is an elegant way to do this?
I only need a lock when the reload is actually happening, not at other times.
I looked at java locks(Read write), Conditions, CyclicBarriers, Countdownlatches
and so on, but not sure what is the right approach for this.
Upvotes: 2
Views: 110
Reputation: 115
Since you want to invalidate all the caches at the same time, you can
The most elegant option would be to use something ready like spring cache (if you are using spring), it also manages distributed caches
Upvotes: 1
Reputation: 19237
If you create new maps, then the readers will need to have a way to get the new map's reference anyway. So instead of referencing directly mapX, keep a reference to an object that holds all the maps. That can be replaced atomicly as you just assign the new Object's reference, like you did in your example. Instead of using map1, you'll have holder.map1 in every place.
class Holder {
Map map1;
Map map2;
}
class Reader {
Holder holder;
void read() {
writer.getHolder().map1.get("x");
}
}
class Writer {
Holder holder;
Holder getHolder() {
return holder;
}
void reload() {
Holder newHolder = new Holder();
newHolder.map1 = createNewMap1WithLatestData();
newHolder.map2 = createNewMap2WithLatestData();
holder = newHolder; // this is atomic
}
}
Upvotes: 1
Reputation: 34900
You provide a very little amount of code, so the answer will be similar. Yes, you need ReadWriteLock
. Please read tutorials about it. In brief, you always allow reading maps (read lock). But when you want to synchronise their initialization, you "turn on" write lock, this locks all lockable blocks and do not allow reading or writing to maps while you are initializating them.
Upvotes: 0