Примеры ошибок, обнаруженных с помощью диагностики V6102
V6102. Inconsistent synchronization of a field. Consider synchronizing the field on all usages.
Apache Solr
V6102 Inconsistent synchronization of the 'byDirectoryCache' field. Consider synchronizing the field on all usages. CachingDirectoryFactory.java 92, CachingDirectoryFactory.java 228
public abstract class CachingDirectoryFactory extends DirectoryFactory {
....
private static final Logger log = LoggerFactory.getLogger(....);
protected Map<String, CacheValue> byPathCache = new HashMap<>();
protected IdentityHashMap<Directory, CacheValue> byDirectoryCache =
new IdentityHashMap<>();
....
private void removeFromCache(CacheValue v) {
log.debug("Removing from cache: {}", v);
byDirectoryCache.remove(v.directory);
byPathCache.remove(v.path);
}
}
Apache Kafka
V6102 Inconsistent synchronization of the 'metrics' field. Consider synchronizing the field on all usages. Sensor.java 49, Sensor.java 254
private final Map<MetricName, KafkaMetric> metrics;
public void checkQuotas(long timeMs) { // <=
for (KafkaMetric metric : this.metrics.values()) {
MetricConfig config = metric.config();
if (config != null) {
....
}
}
....
}
public synchronized boolean add(CompoundStat stat, // <=
MetricConfig config) {
....
if (!metrics.containsKey(metric.metricName())) {
metrics.put(metric.metricName(), metric);
}
....
}
public synchronized boolean add(MetricName metricName, // <=
MeasurableStat stat,
MetricConfig config) {
if (hasExpired()) {
return false;
} else if (metrics.containsKey(metricName)) {
return true;
} else {
....
metrics.put(metric.metricName(), metric);
return true;
}
}
Apache Kafka
V6102 Inconsistent synchronization of the 'prefixKeyFormatter' field. Consider synchronizing the field on all usages. LogicalKeyValueSegment.java 60, LogicalKeyValueSegment.java 247
private final PrefixKeyFormatter prefixKeyFormatter;
@Override
public synchronized void destroy() { // <=
....
Bytes keyPrefix = prefixKeyFormatter.getPrefix();
....
}
@Override
public void addToBatch(....) { // <=
physicalStore.addToBatch(
new KeyValue<>(
prefixKeyFormatter.addPrefix(record.key),
record.value
), batch
);
}
@Override
public synchronized void deleteRange(....) { // <=
physicalStore.deleteRange(
prefixKeyFormatter.addPrefix(keyFrom),
prefixKeyFormatter.addPrefix(keyTo)
);
}
@Override
public synchronized void put(....) { // <=
physicalStore.put(
prefixKeyFormatter.addPrefix(key),
value
);
}