Java 从不同的线程访问Lucene IndexWriter
用法 我在Atlassian JIRA 6.4.1的插件中使用Lucene IndexWriter创建自己的索引。IndexWriter用于JIRA框架创建的组件(JIRA使用spring框架) 该组件由从索引中写入和读取的不同线程使用。IndexWriter是在第一次使用时创建的,所有其他线程始终使用相同的IndexWriter实例 IndexWriter只有在插件卸载或JIRA关闭后才关闭(在这两者之间,我只是在成功写入后调用commit),这就是我的问题 问题 该组件实现org.springframework.beans.factory.DisposableBean接口。在方法destroy(卸载或关机时调用)中,我希望关闭IndexWriter,但关闭IndexWriter的线程与创建IndexWriter的线程不同。发生的情况是,我得到以下异常:Java 从不同的线程访问Lucene IndexWriter,java,spring,multithreading,lucene,jira,Java,Spring,Multithreading,Lucene,Jira,用法 我在Atlassian JIRA 6.4.1的插件中使用Lucene IndexWriter创建自己的索引。IndexWriter用于JIRA框架创建的组件(JIRA使用spring框架) 该组件由从索引中写入和读取的不同线程使用。IndexWriter是在第一次使用时创建的,所有其他线程始终使用相同的IndexWriter实例 IndexWriter只有在插件卸载或JIRA关闭后才关闭(在这两者之间,我只是在成功写入后调用commit),这就是我的问题 问题 该组件实现org.sprin
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
at com.atlassian.jira.util.LuceneDirectoryUtilsImpl$UtilConcurrentLock.release(LuceneDirectoryUtilsImpl.java:183)
at org.apache.lucene.index.IndexWriter.closeInternal(IndexWriter.java:1884)
at org.apache.lucene.index.IndexWriter.close(IndexWriter.java:1814)
at org.apache.lucene.index.IndexWriter.close(IndexWriter.java:1778)
发生此异常的原因是,在IndexWriter的构造函数中获得生成的写锁绑定到另一个线程,作为尝试关闭IndexWriter的线程
据我所知,我无法控制哪个线程生成我的组件,哪个线程销毁我的组件,因为这是由JIRA和spring框架处理的
我现在的问题是,如何正确关闭IndexWriter而不出现此异常?
版本:lucene-core-3.3.0-atlassian-1.jar(因此看起来像是atlassian的修改版)理论上,IndexWriter是完全线程安全的。但是异常是由ReentrantLock引起的,而不是由Lucene引起的。你能坚持最初的线程吗?因为我在JIRA插件中使用IndexWriter,组件的创建和销毁在JIRA(spring framework)中的ComponentContainer中处理,所以我还没有找到坚持线程的方法。我目前正在考虑的一个解决方案是,每次更新/删除索引时,我都会创建一个新的IndexWriter实例,并在操作后关闭IndexWriter。但这只是一种变通方法,而且成本很高。这很遗憾,因为
ReentrantLock$Sync.tryRelease
会显式检查您是否处于调用lock
的同一线程中。。。