From: Robert Varga Date: Mon, 15 Sep 2014 11:29:08 +0000 (+0200) Subject: BUG-650: make ReadOnlyTrieMap concurrent X-Git-Tag: release/helium~18 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=5d396ccc3ebdc9bcb0494393a5df347a5bdbc25f;p=yangtools.git BUG-650: make ReadOnlyTrieMap concurrent ReadOnlyTrieMap.delegate() guarded instantiation with a synchronized block. This is not strictly necessary as readOnly is already volatile. We can take snapshots concurrently and then perform a simple CAS to see if we raced with the other thread. Change-Id: I4e957627a6d7b10bb10fb92a8e210c1d1af22b14 Signed-off-by: Robert Varga --- diff --git a/common/util/src/main/java/org/opendaylight/yangtools/util/ReadOnlyTrieMap.java b/common/util/src/main/java/org/opendaylight/yangtools/util/ReadOnlyTrieMap.java index 4d429f1aaa..0082ff3f5f 100644 --- a/common/util/src/main/java/org/opendaylight/yangtools/util/ReadOnlyTrieMap.java +++ b/common/util/src/main/java/org/opendaylight/yangtools/util/ReadOnlyTrieMap.java @@ -7,14 +7,13 @@ */ package org.opendaylight.yangtools.util; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.google.common.base.Preconditions; import com.google.common.collect.ForwardingMap; import com.romix.scala.collection.concurrent.TrieMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A read-only facade in front of a TrieMap. This is what we give out from @@ -24,6 +23,9 @@ import com.romix.scala.collection.concurrent.TrieMap; * changes, we can cache it for future reference. */ final class ReadOnlyTrieMap extends ForwardingMap { + @SuppressWarnings("rawtypes") + private static final AtomicReferenceFieldUpdater UPDATER = + AtomicReferenceFieldUpdater.newUpdater(ReadOnlyTrieMap.class, TrieMap.class, "readOnly"); private static final Logger LOG = LoggerFactory.getLogger(ReadOnlyTrieMap.class); private final TrieMap readWrite; private final int size; @@ -45,15 +47,11 @@ final class ReadOnlyTrieMap extends ForwardingMap { protected Map delegate() { TrieMap ret = readOnly; if (ret == null) { - synchronized (this) { + ret = readWrite.readOnlySnapshot(); + if (!UPDATER.compareAndSet(this, null, ret)) { ret = readOnly; - if (ret == null) { - ret = readWrite.readOnlySnapshot(); - readOnly = ret; - } } } - return ret; }