[英]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. 我在一个groovy脚本中有一些代码,如果某个名称的图形不存在,我会创建一个新的实例。
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). 问题是这是并行运行并且createGraph()调用需要大约60秒,所以有时候我会创建2个图形实例,并且只将其中一个保存到我的地图中(因为它们都会看到地图没有' t包含名称,然后创建它)。 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 . 也就是说,如果我得到3个并发请求来为foo , foo和bar创建图形,我想同时创建foo和bar但不创建第二个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). 使用java.util.concurrent.ConcurrentHashMap
作为graphMap
的类型,以便您知道它可以处理(不同键的)并发添加。 graphName
after intern
ing it : intern
后在graphName
同步: 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. 如果你有两个String
s的内容相同,但在不同的String
对象, synchronized
将无法正常工作,因为它会在不同的对象同步,也不会阻止其他。
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. 但是,当intern()
被赋予一个具有特定内容的String
时,它总是每次为这些内容返回相同的对象,因此在该对象上进行同步将正常工作。
This allows you to block only on the contents of that particular graphName
rather than the whole graphMap
, allowing more concurrency. 这允许您仅阻止特定graphName
的内容而不是整个graphMap
,从而允许更多的并发性。 It also prevents any wasted work of adding a value for that key twice. 它还可以防止任何浪费的工作,即为该键添加两次值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.