К счастью, в последних версиях (3.x или поздней версии 2.x) они добавили метод, чтобы сообщить вам, было ли какое-либо письмо после открытия поисковика. IndexReader.isCurrent () сообщит вам, произошли ли какие-либо изменения с момента открытия этой программы или нет. Таким образом, вы, вероятно, создадите простой класс-обертку, который инкапсулирует как чтение, так и запись, и с некоторой простой синхронизацией вы можете предоставить 1 класс, который управляет всем этим между всеми потоками.
Вот примерно то, что я делаю:
public class ArchiveIndex {
private IndexSearcher search;
private AtomicInteger activeSearches = new AtomicInteger(0);
private IndexWriter writer;
private AtomicInteger activeWrites = new AtomicInteger(0);
public List<Document> search( ... ) {
synchronized( this ) {
if( search != null && !search.getIndexReader().isCurrent() && activeSearches.get() == 0 ) {
searcher.close();
searcher = null;
}
if( search == null ) {
searcher = new IndexSearcher(...);
}
}
activeSearches.increment();
try {
// do you searching
} finally {
activeSearches.decrement();
}
// do you searching
}
public void addDocuments( List<Document> docs ) {
synchronized( this ) {
if( writer == null ) {
writer = new IndexWriter(...);
}
}
try {
activeWrites.incrementAndGet();
// do you writes here.
} finally {
synchronized( this ) {
int writers = activeWrites.decrementAndGet();
if( writers == 0 ) {
writer.close();
writer = null;
}
}
}
}
}
Итак, у меня есть один класс, который я использую как для читателей, так и для писателей. Обратите внимание, что этот класс позволяет писать и читать одновременно, и несколько читателей могут выполнять поиск одновременно. Единственная синхронизация - это быстрые проверки, чтобы увидеть, нужно ли вам снова открыть поисковик / писатель. Я не синхронизировал на уровне методов, который позволял бы только одному читателю / писателю за раз, что было бы плохой производительностью. Если есть активные поисковики, вы не можете отказаться от поисковика. Так что, если к вам придет много читателей, просто выполните поиск без изменений. Как только он иссякнет, следующий одинокий искатель снова откроет грязный искатель. Это может быть полезно для сайтов с небольшим объемом, где будет пауза в трафике. Это все еще может вызвать голод (то есть вы всегда читаете все более и более старые результаты). Вы можете добавить логику, чтобы просто остановить и повторно инициализировать, если время, которое было замечено как грязное, старше X, в противном случае мы ленивы, как сейчас. Таким образом, вам гарантированно, что поиск никогда не будет старше X.
С писателями можно обращаться практически одинаково. Я часто вспоминаю закрытие писателя, чтобы читатель мог заметить его изменение (зафиксировать). Я не очень хорошо описал это, но это почти тот же способ поиска. Если есть активные писатели, вы не можете закрыть писателя. Если вы последний писатель, закройте писателя. Вы поняли идею.