diff --git a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java index 8194b888615e7..ad32fb4651e3d 100644 --- a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java +++ b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java @@ -114,19 +114,24 @@ public > IFD getForField(MappedFieldType fieldType final String fieldName = fieldType.name(); IndexFieldData.Builder builder = fieldType.fielddataBuilder(fullyQualifiedIndexName); - IndexFieldDataCache cache; - synchronized (this) { - cache = fieldDataCaches.get(fieldName); - if (cache == null) { - String cacheType = indexSettings.getValue(INDEX_FIELDDATA_CACHE_KEY); - if (FIELDDATA_CACHE_VALUE_NODE.equals(cacheType)) { - cache = indicesFieldDataCache.buildIndexFieldDataCache(listener, index(), fieldName); - } else if ("none".equals(cacheType)){ - cache = new IndexFieldDataCache.None(); - } else { - throw new IllegalArgumentException("cache type not supported [" + cacheType + "] for field [" + fieldName + "]"); + IndexFieldDataCache cache = fieldDataCaches.get(fieldName); + if (cache == null) { + //for perf reason, only synchronize when cache is null + synchronized (this) { + cache = fieldDataCaches.get(fieldName); + //double checked locking to make sure it is thread safe + //especially when other threads calling clear() or clearField() + if (cache == null) { + String cacheType = indexSettings.getValue(INDEX_FIELDDATA_CACHE_KEY); + if (FIELDDATA_CACHE_VALUE_NODE.equals(cacheType)) { + cache = indicesFieldDataCache.buildIndexFieldDataCache(listener, index(), fieldName); + } else if ("none".equals(cacheType)){ + cache = new IndexFieldDataCache.None(); + } else { + throw new IllegalArgumentException("cache type not supported [" + cacheType + "] for field [" + fieldName + "]"); + } + fieldDataCaches.put(fieldName, cache); } - fieldDataCaches.put(fieldName, cache); } }