简体   繁体   中英

Groovy(/Java): Lock on unique values of a variable?

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:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM