Java:在多线程中对锁定对象使用字符串常量或内部字符串可以吗?

Java:在多线程中对锁定对象使用字符串常量或内部字符串可以吗?,java,multithreading,Java,Multithreading,代码片段如下所示: Map<Class<?>, ConcurrentHashMap<String, T>> m; ... ... map = m.get(clazz); if(map.get(param) == null){ String str = clazz.getSimpleName()+param; String internedStr = str.intern(); synchronized(internedStr){ if(m

代码片段如下所示:

Map<Class<?>, ConcurrentHashMap<String, T>> m;
...
...
map = m.get(clazz);
if(map.get(param) == null){
  String str = clazz.getSimpleName()+param;
  String internedStr = str.intern();
  synchronized(internedStr){
     if(map.get(param) == null){
     ... // time-consuming task
        map.put(param, someValue);
     }
  }
}

Map
ConcurrentHashMap.computeIfAbsent()
,用于救援。为此,您需要确保内部映射是
ConcurrentHashMaps
,因此它是线程安全的。但是,它使代码简单得多:去掉了
intern()
,去掉了双重检查锁定,去掉了
synchronized
。更不用说代码读起来好多了

Map<Class<?>, ConcurrentHashMap<String, T>> m;
...
map = m.get(clazz);
Result r = map.computeIfAbsent(param, key -> {
    // Perform time consuming task
    return result;
});

Map
ConcurrentHashMap.computeIfAbsent()
,用于救援。为此,您需要确保内部映射是
ConcurrentHashMaps
,因此它是线程安全的。但是,它使代码简单得多:去掉了
intern()
,去掉了双重检查锁定,去掉了
synchronized
。更不用说代码读起来好多了

Map<Class<?>, ConcurrentHashMap<String, T>> m;
...
map = m.get(clazz);
Result r = map.computeIfAbsent(param, key -> {
    // Perform time consuming task
    return result;
});


Map您可以使用任何简单对象,如final object lock=new object();还要确保将引用标记为final。

您可以使用任何简单对象,如final object lock=new object();还要确保将引用标记为final。

string类的开发是为了使它们的对象是不可变的……我认为最大的问题是它不清楚。你能从更广泛的意义上解释一下你想做什么吗?为什么不在类对象上同步?从外观上看,为什么不直接使用
map
作为你要同步的对象呢?尽管如此,Kayaman的解决方案似乎是一个更好的答案。@matt因为目标是在尽可能小的部分上获得锁定,即类和参数。由于您无法执行
同步(map,param)
所讨论的代码试图通过组合名称并将其插入,从而提供细粒度的锁对象。然而,使用
synchronized
应该是最近的最后一项工作,因为
java.util.concurrent
中充满了漂亮而高效的同步原语。你能从更广泛的意义上解释一下你想做什么吗?为什么不在类对象上同步?从外观上看,为什么不直接使用
map
作为你要同步的对象呢?尽管如此,Kayaman的解决方案似乎是一个更好的答案。@matt因为目标是在尽可能小的部分上获得锁定,即类和参数。由于您无法执行
同步(map,param)
所讨论的代码试图通过组合名称并将其插入,从而提供细粒度的锁对象。然而,使用
synchronized
应该是这些天的最后一项工作,因为
java.util.concurrent
中充满了漂亮而高效的同步原语。这个答案是否类似于ops问题中的
map
上的同步?此外,如果您查看文档:“其他线程在此地图上尝试的某些更新操作可能会在计算过程中被阻止,因此计算应该简短。”不,这与在地图上同步锁定整个地图不同。这类似于在
param
上同步,但不会影响具有相同
param
的其他内部映射(即基本上
synchronized(map,param)
。至于潜在的更新(我怀疑是否有),它将阻止它们是的,这是一件好事。原始代码将允许丢失更新(除非他们做了整个实习生同步的事情)。它将阻止对地图的更新,哪些更新不清楚。这与在
map
上同步类似。就“锁的大小”而言,我会说
map
>ConcurrentHashMap>internedString。至于可用性,我会说你的方法更好。你错了。如果你在
map
上同步,它会阻止所有
params
。我的方法仅阻止单个
param
的操作。这正是作者所寻找的。这是问题中的代码版本,不会进行黑客攻击。它仅阻止特定映射上的所有参数的操作,当它们位于另一个同步块中时。此外,您还没有解决这个问题,文档中特别提到“短而简单”。这个答案与ops问题中的
map
上的同步类似吗?如果您查看文档:“在计算过程中,其他线程在此map上尝试的一些更新操作可能会被阻止,因此计算应该短而简单”不,这与在地图上同步锁定整个地图不同。这类似于在
param
上同步,但不会影响具有相同
param
的其他内部地图(即基本上
synchronized(map,param)
。至于潜在的更新(我怀疑是否有),它会阻止它们是的,这是一件好事。原始代码会允许丢失更新(除非他们执行整个实习生同步操作)。它将阻止对地图的更新,哪些更新不清楚。这与在
map
上同步类似。就“锁的大小”而言,我会说
map
>ConcurrentHashMap>internedString。至于可用性,我会说你的方法更好。你错了。如果你在
map
上同步,它会阻止所有
params
。我的方法仅阻止单个
param
的操作。这正是作者所寻找的。这是问题中的代码版本,不会进行黑客攻击。它仅阻止特定映射上的所有参数的操作,当它们位于另一个同步块中时。此外,您还没有解决这个问题,文档特别说“简短”。这与问题无关。这与问题无关。