我有一個使用位於特定目錄中的索引的方法。正在同步和IO文件
public class TestSearchEngine implements SearchEngine<Tag> {
private static final String INDEX_PATH = "/test/index";
private Directory directory;
@Inject private TagDAO tagDAO;
private int organizationId;
@Override
public void add(Tag tag) {
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35));
IndexWriter indexWriter = getIndexWriter(indexWriterConfig);
//Create document
Document document = new Document();
document.add(new Field("id", String.valueOf(tag.getId()), Field.Store.YES, Field.Index.NOT_ANALYZED));
document.add(new Field("title", tag.getTitle(), Field.Store.NO, Field.Index.ANALYZED));
try {
indexWriter.addDocument(document);
indexWriter.close();
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public synchronized void setDirectory(int organizationId) throws IOException {
this.organizationId = organizationId;
File path = new File(INDEX_PATH + "/" + String.valueOf(organizationId));
//If path does not exist, create it and create new index for organization
if(!path.exists()) {
path.mkdirs();
buildCompleteIndex(organizationId, false);
}
this.directory = FSDirectory.open(path); //Open directory
}
private void buildCompleteIndex(int organizationId, boolean rebuildDir) {
if(rebuildDir) {
File path = new File(INDEX_PATH + "/" + String.valueOf(organizationId));
try {
Utils.deleteDirectory(path);
} catch (IOException e) {
throw new LuceneIndexException("Error rebuilding index directory.", e);
}
path.mkdirs();
}
List<Tag> tagList = tagDAO.findAll(organizationId);
for(Tag tag : tagList) {
add(tag);
}
}
private IndexReader getIndexReader() {
try {
return IndexReader.open(directory);
} catch (CorruptIndexException e) {
buildCompleteIndex(organizationId, true);
} catch (IOException e) {
throw new LuceneIndexException("IOException prevented IndexReader from opening Index.", e);
} catch(NullPointerException e) {
throw new LuceneIndexException("Index resource not available.", e);
}
return null;
}
}
在某些情況下,我趕上如果出於某種原因該指數成爲腐敗的一個例外,或者它只是已尚未創建。在這種情況下,將調用buildCompleteIndex()方法,該方法刪除目錄並從數據源重新創建索引。
在多線程環境中,如何防止另一個線程創建類的實例,並使用調用該目錄時刪除或正在重建的方法? setDirectory()方法必須在任何其他方法工作之前調用,所以我假設在該方法上設置同步會解決這個問題,但是如果在線程已經存在的情況下該目錄變爲破壞,那麼它將如何開始調用重建方法在同一時間?換句話說,我對在多線程環境中刪除和更新IO文件的正確方法有點困惑。一些建議,將不勝感激。
所以我可以理解。互斥對象的要點是什麼?你能解釋一下怎麼工作嗎? – ryandlf 2012-03-23 19:36:42
你必須有一些共同的東西來同步。你擁有它的方式會與「this」同步,這取決於創建實例的線程。使用靜態互斥鎖,所有實例都將與同一個實例同步,或者在這種情況下互斥鎖。也可能有更好的方法來實現這一點,但我認爲這將適用於你的用例。 – tjg184 2012-03-23 20:10:05
好的...有道理。感謝您的解釋。 – ryandlf 2012-03-23 20:32:38