특정 디렉터리에있는 인덱스를 사용하는 방법이 있습니다. 특정 상황에서동기화 및 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
동기화 할 항목이 있어야합니다. 당신이 가지고 있던 방식은 "this"와 동기화 될 것이고, 이는 스레드가 인스턴스를 생성 한 것에 따라 다릅니다. 정적 뮤텍스를 사용하면 모든 인스턴스가 동일한 인스턴스 또는이 경우 뮤텍스와 동기화됩니다. 이 기능을 구현하는 데 더 좋은 방법이있을 수도 있지만 사용 사례와 함께 사용할 수 있다고 생각합니다. – tjg184
좋습니다 ... 말이 맞습니다. 설명 해줘서 고마워. – ryandlf