diff --git a/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/BeanCache.java b/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/BeanCache.java index 25e2c04f..af8f620f 100644 --- a/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/BeanCache.java +++ b/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/BeanCache.java @@ -15,7 +15,7 @@ import java.util.Collections; import java.util.IdentityHashMap; import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import org.eclipse.sisu.BeanEntry; @@ -28,7 +28,6 @@ */ @SuppressWarnings( { "rawtypes", "unchecked" } ) final class BeanCache - extends AtomicReference { // ---------------------------------------------------------------------- // Constants @@ -36,10 +35,15 @@ final class BeanCache private static final long serialVersionUID = 1L; + private static final AtomicReferenceFieldUpdater MAPPING_UPDATER = + AtomicReferenceFieldUpdater.newUpdater( BeanCache.class, Object.class, "mapping" ); + // ---------------------------------------------------------------------- // Implementation fields // ---------------------------------------------------------------------- + private volatile Object mapping; + private Map, BeanEntry> readCache; private volatile boolean mutated; @@ -67,7 +71,7 @@ public BeanEntry create( final Q qualifier, final Binding binding, fina */ do { - o = get(); + o = mapping; if ( null == o ) { // most common case: adding the one (and-only) entry @@ -96,7 +100,7 @@ else if ( o instanceof LazyBeanEntry ) } } } - while ( !compareAndSet( o, n ) ); + while ( !MAPPING_UPDATER.compareAndSet( this, o, n ) ); if ( n instanceof IdentityHashMap ) { @@ -117,7 +121,7 @@ public Map, BeanEntry> flush() { if ( mutated ) { - readCache = (Map) ( (IdentityHashMap) get() ).clone(); + readCache = (Map) ( (IdentityHashMap) mapping ).clone(); mutated = false; } } @@ -132,7 +136,7 @@ public Map, BeanEntry> flush() */ public Iterable> bindings() { - final Object o = get(); + final Object o = mapping; if ( null == o ) { return Collections.EMPTY_SET; @@ -164,7 +168,7 @@ public BeanEntry remove( final Binding binding ) */ do { - o = get(); + o = mapping; if ( null == o ) { return null; @@ -191,7 +195,7 @@ else if ( o instanceof LazyBeanEntry ) } } } - while ( !compareAndSet( o, n ) ); + while ( !MAPPING_UPDATER.compareAndSet( this, o, n ) ); return oldBean; } diff --git a/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedSequence.java b/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedSequence.java index d6e91088..c54bec26 100644 --- a/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedSequence.java +++ b/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedSequence.java @@ -15,13 +15,12 @@ import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; -import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; /** * Ordered {@link List} that arranges elements by descending rank; supports concurrent iteration and modification. */ final class RankedSequence - extends AtomicReference implements Iterable { // ---------------------------------------------------------------------- @@ -30,6 +29,16 @@ final class RankedSequence private static final long serialVersionUID = 1L; + @SuppressWarnings( "rawtypes" ) + private static final AtomicReferenceFieldUpdater CONTENT_UPDATER = + AtomicReferenceFieldUpdater.newUpdater( RankedSequence.class, Content.class, "content" ); + + // ---------------------------------------------------------------------- + // Implementation fields + // ---------------------------------------------------------------------- + + volatile Content content; + // ---------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------- @@ -43,7 +52,7 @@ final class RankedSequence { if ( null != sequence ) { - set( sequence.get() ); + content = sequence.content; } } @@ -64,28 +73,28 @@ public void insert( final T element, final int rank ) Content o, n; do { - n = null != ( o = get() ) ? o.insert( element, rank ) : new Content( element, rank ); + n = null != ( o = content ) ? o.insert( element, rank ) : new Content( element, rank ); } - while ( !compareAndSet( o, n ) ); + while ( !CONTENT_UPDATER.compareAndSet( this, o, n ) ); } @SuppressWarnings( "unchecked" ) public T peek() { - final Content content = get(); - return null != content ? (T) content.objs[0] : null; + final Content snapshot = content; + return null != snapshot ? (T) snapshot.objs[0] : null; } public boolean contains( final Object element ) { - final Content content = get(); - return null != content && content.indexOf( element ) >= 0; + final Content snapshot = content; + return null != snapshot && snapshot.indexOf( element ) >= 0; } public boolean containsThis( final Object element ) { - final Content content = get(); - return null != content && content.indexOfThis( element ) >= 0; + final Content snapshot = content; + return null != snapshot && snapshot.indexOfThis( element ) >= 0; } @SuppressWarnings( "unchecked" ) @@ -95,13 +104,13 @@ public T remove( final Object element ) int index; do { - if ( null == ( o = get() ) || ( index = o.indexOf( element ) ) < 0 ) + if ( null == ( o = content ) || ( index = o.indexOf( element ) ) < 0 ) { return null; } n = o.remove( index ); } - while ( !compareAndSet( o, n ) ); + while ( !CONTENT_UPDATER.compareAndSet( this, o, n ) ); return (T) o.objs[index]; } @@ -112,13 +121,13 @@ public boolean removeThis( final T element ) do { final int index; - if ( null == ( o = get() ) || ( index = o.indexOfThis( element ) ) < 0 ) + if ( null == ( o = content ) || ( index = o.indexOfThis( element ) ) < 0 ) { return false; } n = o.remove( index ); } - while ( !compareAndSet( o, n ) ); + while ( !CONTENT_UPDATER.compareAndSet( this, o, n ) ); return true; } @@ -126,24 +135,24 @@ public boolean removeThis( final T element ) @SuppressWarnings( { "rawtypes", "unchecked" } ) public Iterable snapshot() { - final Content content = get(); - return null != content ? (List) Arrays.asList( content.objs ) : Collections.EMPTY_SET; + final Content snapshot = content; + return null != snapshot ? (List) Arrays.asList( snapshot.objs ) : Collections.EMPTY_SET; } public void clear() { - set( null ); + content = null; } public boolean isEmpty() { - return null == get(); + return null == content; } public int size() { - final Content content = get(); - return null != content ? content.objs.length : 0; + final Content snapshot = content; + return null != snapshot ? snapshot.objs.length : 0; } public Itr iterator() @@ -349,7 +358,7 @@ final class Itr // Implementation fields // ---------------------------------------------------------------------- - private Content content; + private Content snapshot; private T nextObj; @@ -368,16 +377,16 @@ public boolean hasNext() { return true; } - final Content newContent = get(); - if ( content != newContent ) + final Content newSnapshot = content; + if ( snapshot != newSnapshot ) { - index = null != newContent ? safeBinarySearch( newContent.uids, nextUID ) : -1; - content = newContent; + index = null != newSnapshot ? safeBinarySearch( newSnapshot.uids, nextUID ) : -1; + snapshot = newSnapshot; } - if ( index >= 0 && index < content.objs.length ) + if ( index >= 0 && index < snapshot.objs.length ) { - nextObj = (T) content.objs[index]; - nextUID = content.uids[index]; + nextObj = (T) snapshot.objs[index]; + nextUID = snapshot.uids[index]; return true; } return false; @@ -392,15 +401,15 @@ public boolean hasNext( final int rank ) { return uid2rank( nextUID ) >= rank; } - final Content newContent = get(); - if ( content != newContent ) + final Content newSnapshot = content; + if ( snapshot != newSnapshot ) { - index = null != newContent ? safeBinarySearch( newContent.uids, nextUID ) : -1; - content = newContent; + index = null != newSnapshot ? safeBinarySearch( newSnapshot.uids, nextUID ) : -1; + snapshot = newSnapshot; } - if ( index >= 0 && index < content.uids.length ) + if ( index >= 0 && index < snapshot.uids.length ) { - return uid2rank( content.uids[index] ) >= rank; + return uid2rank( snapshot.uids[index] ) >= rank; } return false; }