I have some code in a groovy script where if a graph for a certain name does not exist, I create a new instance of it.
if (!graphMap.contains(graphName)) {
newGraph = createGraph(graphName)
graphMap.put(graphName, newGraph)
}
The problem is this is running in parallel and the createGraph() call takes ~60 seconds, so sometimes I'll create 2 instances of the graph and only save 1 of them to my map (because they'll both see the map doesn't contain the name and then create it). It's my understanding that I can lock on the map to avoid this problem, like so:
synchronized(graphMap) {
if (!graphMap.contains(graphName)) {
newGraph = createGraph(graphName)
graphMap.put(graphName, newGraph)
}
}
But the problem with this is that creating a graph can take a while, and I want to be able to create graphs for several different names at the same time. That is to say, if I get 3 concurrent requests to create graphs for foo , foo , and bar , I want to create foo and bar concurrently but not create the 2nd foo . Is it possible for me to synchronize not on the map, but instead on specific name values?
A quick solution is to:
java.util.concurrent.ConcurrentHashMap
as the type of graphMap
so that you know it can handle concurrent additions (of different keys). graphName
after intern
ing it : graphName = graphName.intern();
synchronized(graphName) {
if (!graphMap.contains(graphName)) {
newGraph = createGraph(graphName)
graphMap.put(graphName, newGraph)
}
}
If you have two String
s with the same contents but in different String
objects, synchronized
won't work properly, as it will synchronize on different objects and neither will block the other.
However, when intern()
is given a String
with certain contents, it always returns the same object every time for those contents, so synchronizing on that object will work properly.
This allows you to block only on the contents of that particular graphName
rather than the whole graphMap
, allowing more concurrency. It also prevents any wasted work of adding a value for that key twice.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.