This is by no means an easy task. I had to write quite a lot of code to achieve it (unfortunately, it is in Clojure, so Java code samples are not at hand). The basic principle is to have a thread-safe link to your IndexSearcher, available for both index reading code and index building code. The index builder begins to create a new index in the background; this does not interfere with existing indexes. Upon completion, it enters the synchronized block, closes IndexReader and IndexSearcher, opens a new IndexReader and updates the global IndexSearcher link to the IndexSearcher created from it. All read code must be synchronized with the same lock as the one associated with the specified synchronized block. A better alternative is to use a ReentrantReadWriteLock instead of a synchronized block. This will avoid excessive competition between many read streams.
After initialization during normal operation, you can use the NRTManager to simultaneously read the index and create incremental updates.
source share