我希望跟踪在synchronized
块中被修改的队列中的位置。因此,我需要一个反变量。通常我会使用AtomicInteger
,但这里需要吗?
PriorityBlockingQueue<TfIdfScore> allScores = sharedFeatureNameToScores.get(featureName);
synchronized (allScores) {
AtomicInteger position = positionCounterMap.get(featureName);
position.getAndAdd(1);
// Do other stuff..
}
或者我也可以使用int
或Integer
吗?synchronized
块是否保护块内的所有操作?
在本例中,position
和allScores
依赖于同一个featureName
。
发布于 2015-05-26 06:35:36
如果您正在编写所有的代码(并给予适当的注意),那么您不需要同时使用synchronized
和原子类型。只需确保给定地图上的所有操作及其包含的计数器在同一对象上同步,而它们则是这样做的.代码的那一部分应该是线程安全的。
另一方面,如果您担心有人会忘记同步,那么原子类型可能解决不了这个问题。一个更好的解决方案是确保映射和计数器封装得很好,以减少出错的范围。(如果您可以减少可以访问状态的代码数量,那么需要检查线程安全性的地方就减少了。)
同步块是否保护块内的所有操作?
不一定。
如果有其他代码访问或更新数据结构,并且该代码在正确的互斥对象上没有同步,例如同一个allScores
实例,则仍然存在线程安全问题。
发布于 2015-05-26 06:07:14
同步比原子或易失性更严格。因此,您不需要在同步中使用原子。
已同步
同步方法支持防止线程干扰和内存一致性错误的简单策略:如果一个对象对多个线程可见,则通过同步方法对该对象的变量进行所有读或写操作。
易失性
易失性字段意味着变量不会被缓存在处理器内核/线程中。因此,每个核心/线程只有一个变量副本。
原子性
java.util.concurrent.atomic包定义了支持对单个变量进行原子操作的类。所有类都有get和set方法,它们对易失性变量进行读写。也就是说,在与同一变量上的任何后续get建立关系之前,集合就会发生。原子compareAndSet方法还具有这些内存一致性特性,适用于整数原子变量的简单原子算术方法也是如此。
发布于 2015-05-26 06:47:13
在您的代码中,您使用两个使用featureName的不同对象:sharedFeatureNameToScores
和positionCounterMap
。
为了保证您的代码是线程安全的,您需要确保对它们的修改使用相同的锁(代码中的synchronized (allScores)
)。一旦满足了这一要求,就不需要使用AtomicInteger了,因为同步块保护了这两者,所以对positionCounterMap
的访问是在独占模式下进行的。
https://stackoverflow.com/questions/30460875
复制