Index: lucene/src/java/org/apache/lucene/index/IndexReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/IndexReader.java (revision 1221367) +++ lucene/src/java/org/apache/lucene/index/IndexReader.java (working copy) @@ -22,10 +22,11 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.document.Document; @@ -36,7 +37,6 @@ import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CommandLineUtil; -import org.apache.lucene.util.MapBackedSet; import org.apache.lucene.util.ReaderUtil; // for javadocs /** IndexReader is an abstract class, providing an interface for accessing an @@ -84,7 +84,7 @@ } private final Set readerClosedListeners = - new MapBackedSet(new ConcurrentHashMap()); + Collections.synchronizedSet(new LinkedHashSet()); /** Expert: adds a {@link ReaderClosedListener}. The * provided listener will be invoked when this reader is closed. @@ -104,8 +104,10 @@ } private final void notifyReaderClosedListeners() { - for(ReaderClosedListener listener : readerClosedListeners) { - listener.onClose(this); + synchronized(readerClosedListeners) { + for(ReaderClosedListener listener : readerClosedListeners) { + listener.onClose(this); + } } } Index: lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java =================================================================== --- lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java (revision 1221367) +++ lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java (working copy) @@ -18,8 +18,9 @@ */ import java.io.IOException; +import java.util.Collections; +import java.util.LinkedHashSet; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.codecs.Codec; @@ -34,7 +35,6 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.util.IOUtils; -import org.apache.lucene.util.MapBackedSet; /** Holds core readers that are shared (unchanged) when * SegmentReader is cloned or reopened */ @@ -67,8 +67,8 @@ CompoundFileDirectory cfsReader; CompoundFileDirectory storeCFSReader; - final Set coreClosedListeners = - new MapBackedSet(new ConcurrentHashMap()); + private final Set coreClosedListeners = + Collections.synchronizedSet(new LinkedHashSet()); SegmentCoreReaders(SegmentReader owner, Directory dir, SegmentInfo si, IOContext context, int termsIndexDivisor) throws IOException { @@ -138,12 +138,26 @@ if (ref.decrementAndGet() == 0) { IOUtils.close(fields, perDocProducer, termVectorsReaderOrig, fieldsReaderOrig, cfsReader, storeCFSReader, norms); + notifyCoreClosedListeners(); + } + } + + private final void notifyCoreClosedListeners() { + synchronized(coreClosedListeners) { for (CoreClosedListener listener : coreClosedListeners) { listener.onClose(owner); } } } + + void addCoreClosedListener(CoreClosedListener listener) { + coreClosedListeners.add(listener); + } + void removeCoreClosedListener(CoreClosedListener listener) { + coreClosedListeners.remove(listener); + } + synchronized void openDocStores(SegmentInfo si) throws IOException { assert si.name.equals(segment); Index: lucene/src/java/org/apache/lucene/index/SegmentReader.java =================================================================== --- lucene/src/java/org/apache/lucene/index/SegmentReader.java (revision 1221367) +++ lucene/src/java/org/apache/lucene/index/SegmentReader.java (working copy) @@ -595,12 +595,12 @@ /** Expert: adds a CoreClosedListener to this reader's shared core */ public void addCoreClosedListener(CoreClosedListener listener) { ensureOpen(); - core.coreClosedListeners.add(listener); + core.addCoreClosedListener(listener); } /** Expert: removes a CoreClosedListener from this reader's shared core */ public void removeCoreClosedListener(CoreClosedListener listener) { ensureOpen(); - core.coreClosedListeners.remove(listener); + core.removeCoreClosedListener(listener); } }