[導入]Lucene并發訪問


作者: yagesi? 鏈接:http://yagesi.javaeye.com/blog/165604? 發表時間: 2008年02月27日

聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!

在Lucene并發訪問中,如果出現線程沖突,會造成索引文件的損壞,系統出現Lock obtain timed Out異常. 索引文件的臨時目錄會多一個work.lock或者commit.lock的文件,證明你并發訪問出現了問題,索引文件已經損壞...

在Lucene in Action中給出IndexWriter和IndexReader并發訪問操作矩陣,矩陣中描述了兩個操作不能同時執行的描述:

矩陣可以歸納為:

?

  • IndexReader對象在從索引中刪除一個文檔時,IndexWriter對象不能向該索引庫添加文檔
  • IndexWriter對象在索引進行優化時,IndexReader對象不能從其中刪除文檔
  • IndexWriter對象在對索引進行合并時,IndexReader對象也不能從其中刪除文檔

以上三點引自 Lucene in Action 第二章

其實在程序中,到底該索引是否被鎖定,我們可以通過IndexReader類的靜態方法isLocked(Directory)進行判定..我測試過,如果使用IndexWriter訪問索引,那么在我們創建IndexWriter對象的時候,索引文件就會被鎖定,當調用IndexWriter的close方法時,鎖才釋放...當我們使用IndexReader訪問索引文件時,當我們使用open打開索引時,文件不會被鎖定,只有執行deleteDocument方法時才鎖定,IndexReader的close方法時才釋放...

所以在并發訪問索引文件的時候,我們除了要保證IndexWriter和IndexReader它們各自的并發訪問的線程安全外,還要保證IndexWriter和IndexReader之間的并發訪問...

?

下面是我實現的部分代碼:

?

public class IndexManager {private static Analyzer analyzer = null;private static IndexWriter _company_writer = null;private static IndexReader _company_reader = null;private static List<Thread> _company_writer_thread = new ArrayList();private static List<Thread> _company_reader_thread = new ArrayList();static{Paoding paoding = PaodingMaker.make();analyzer =  PaodingAnalyzer.writerMode(paoding);}private IndexManager(){}public static IndexWriter getCompanyIndexWriter(String path,Boolean isReBuild){synchronized(_company_writer_thread){if(_company_writer==null){try {while(true){if(!IndexReader.isLocked(path)){_company_writer = new IndexWriter(path,analyzer,isReBuild);break;}else{try {Thread.sleep(100);Thread.yield();} catch (InterruptedException e) {e.printStackTrace();}}}} catch (CorruptIndexException e) {e.printStackTrace();} catch (LockObtainFailedException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}if(!_company_writer_thread.contains(Thread.currentThread()))_company_writer_thread.add(Thread.currentThread());return _company_writer;}}public static void closeCompanyIndexWriter(){synchronized(_company_writer_thread){if (_company_writer_thread.contains(Thread.currentThread()))_company_writer_thread.remove(Thread.currentThread());if (_company_writer_thread.size() == 0){if (_company_writer != null){try {_company_writer.close();} catch (CorruptIndexException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}_company_writer = null;}}}}public static IndexReader getCompanyIndexReader(String path){synchronized(_company_reader_thread){if(_company_reader==null){try {while(true){if(!IndexReader.isLocked(path)){_company_reader = IndexReader.open(path);break;}else{try {Thread.sleep(20);Thread.yield();} catch (InterruptedException e) {e.printStackTrace();}}}} catch (CorruptIndexException e) {e.printStackTrace();} catch (LockObtainFailedException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}if(!_company_reader_thread.contains(Thread.currentThread()))_company_reader_thread.add(Thread.currentThread());return _company_reader;}}public static void closeCompanyIndexReader(){synchronized(_company_reader_thread){if (_company_reader_thread.contains(Thread.currentThread()))_company_reader_thread.remove(Thread.currentThread());if (_company_reader_thread.size() == 0){if (_company_reader != null){try {_company_reader.close();} catch (CorruptIndexException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}_company_reader = null;}}}}}
?

??

該類使用靜態方法獲取IndexWriter和IndexReader對象,在獲取方法中,要判斷該索引是否被鎖定<IndexReader.isLocked(Directory)方法>,該方法主要為了防止IndexWriter和IndexReader它們之間的并發問題,至于IndexWriter和IndexReader它們自己本身的并發訪問問題,使用了一個線程集合來進行管理,可以確保獲取的訪問對象不會出現同步問題.但是獲取的IndexWriter或者IndexReader對象,在close的時候,一定要調用IndexManager的closeXXXXXXX()方法,這樣線程池才能有效的管理IndexWriter,IndexReader實例線程...

?

Lucene并發訪問問題就介紹到這里,由于剛剛開始學寫帖子,有很多地方詞不達意,表述不清,請大家諒解,我相信:會進步的...謝謝 


本文的討論也很精彩,瀏覽討論>>


JavaEye推薦
  • 快來參加7月17日在成都舉行的SOA中國技術論壇
  • JavaEye問答大賽開始了! 從6月23日 至 7月6日,獎品豐厚 !
  • 北京: 千橡集團暨校內網誠聘軟件研發工程師
  • Oracle專區上線,有Oracle最新文章,重要下載及知識庫等精彩內容,歡迎訪問。
  • 搜狐網站誠聘Java、PHP和C++工程師




文章來源:http://yagesi.javaeye.com/blog/165604

轉載于:https://www.cnblogs.com/schwarzwald/archive/2008/07/05/1236204.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379989.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379989.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379989.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python程序計算給定文本中單詞的出現

Given a text (paragraph) and a word whose occurrence to be found in the text/paragraph, we have to find the how many times word is repeated in the text. 給定一個文本 (段落)&#xff0c;其出現在文本/段落被找到的單詞 &#xff0c;我們必須找到如何詞多次在文本重…

js私有共有成員

在小項目中對于JavaScript使用&#xff0c;只要寫幾個function就行了。但在大型項目中&#xff0c;尤其是在開發追求 良好的用戶體驗的網站中&#xff0c;如SNS,就會 用到大量的JavaScrpt&#xff0c;有時JavaScript的工作量勝過了C#&#xff0c;這時寫一堆function,就會顯得很…

Java——IO(打印流)

1&#xff0c;打印字節流(PrintStream)的概述&#xff1a; 打印流可以很方便的將對象的toString()結果輸出并且自動加上換行&#xff0c;而且可以使用自動刷出的模式 System.out就是一個PrintStream&#xff0c;其默認向控制臺輸出信息 2&#xff0c;使用方式&#xff1a; …

MATLAB中的正態分布檢驗

要對一組樣本進行正態性檢驗&#xff0c;在MATLAB中&#xff0c;一種方法是用normplot畫出樣本&#xff0c;如果都分布在一條直線上&#xff0c;則表明樣本來自正態分布&#xff0c;否則是非正態分布。 MATLAB中也提供了幾種更正式的檢驗方法&#xff1a;kstest Kolmogorov-Smi…

遠控免殺專題(29)-C#加載shellcode免殺-5種方式(VT免殺率8-70)

0x00 免殺能力一覽表 幾點說明&#xff1a; 1、表中標識 √ 說明相應殺毒軟件未檢測出病毒&#xff0c;也就是代表了Bypass。 2、為了更好的對比效果&#xff0c;大部分測試payload均使用msf的windows/meterperter/reverse_tcp模塊生成。 3、由于本機測試時只是安裝了360全家…

kotlin 或 運算_Kotlin程序對兩個數字執行算術運算

kotlin 或 運算Here, we are implementing a Kotlin program to perform various arithmetic operations on two numbers. 在這里&#xff0c;我們正在實現Kotlin程序&#xff0c;以對兩個數字執行各種算術運算 。 Given two numbers a and b, we have to find addition, sub…

2012.1.15---學習筆記

最近學習實踐的內容主要有&#xff1a;1 memcahche的安裝、使用&#xff08;為了減少數據庫壓力而采用的&#xff09;2 linux下的定時任務的配置&#xff0c;crontab3 如何去編寫可配置的php程序&#xff08;加載配置文件&#xff09;1 memcahche的安裝、使用&#xff08;為了減…

WPF界面設計技巧(2)—自定義漂亮的按鈕樣式

上次做了個很酷的不規則窗體&#xff0c;這次我們來弄點好看的按鈕出來&#xff0c;此次將采用純代碼來設計按鈕樣式&#xff0c;不需要 Microsoft Expression Design 輔助了。 首先打開 Microsoft Visual Studio 2008 &#xff0c;新建一個WPF項目&#xff0c;在上面隨便放幾個…

ropgadgets與ret2syscall技術原理

程序&#xff1a; #include <stdio.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <sys/syscall.h> void exploit() { system("/bin/sh"); } void func() { char str[0x20]; read(0,str,0x50); } int…

uboot load address、entry point、 bootm address以及kernel運行地址的意義及聯系

按各地址起作用的順序&#xff0c;uboot引導linux內核啟動涉及到以下地址&#xff1a; load address&#xff1a;entry point&#xff1a; 這兩個地址是mkimage時指定的bootm address&#xff1a;bootm為uboot的一個命令&#xff0c;以此從address啟動kernelkernel運行地址&…

Java——集合(Map集合的兩種迭代)

一&#xff0c;Map集合的第一種迭代 Map集合的第一種迭代&#xff0c;通過get(key)方法&#xff0c;根據鍵去獲取值 package com.wsq.map;import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set;public class Demo2_Iterator { …

如何使用兩個堆棧實現隊列_使用兩個隊列實現堆棧

如何使用兩個堆棧實現隊列Stack and Queue at a glance... 堆疊和排隊一目了然... Stack: 堆棧&#xff1a; The stack is an ordered list where insertion and deletion are done from the same end, top. The last element that entered first is the first one to be del…

接口pk抽象類

作為開發者&#xff0c;誰從來沒有陷入過周而復始地爭論應該是使用接口還是抽象類&#xff1f;這是一場永無休止的爭論&#xff0c;不同陣營的人總是堅定地堅持自己的立場。應當使用接口還是抽象類&#xff1f;對于初學者來說那更是滿頭霧水。這個問題應該考慮一下幾個因素&…

匯編shr命令

右移命令 比如&#xff1a; mov eax,10 shr eax,0x2上面的命令是將eax的值右移兩位&#xff0c;怎么左移呢&#xff1f;首先將eax的值轉為二進制10------》1010&#xff0c;然后右移兩位變成10&#xff0c;所以執行為shr命令&#xff0c;eax的值為十進制的2

iBatis入門和開發環境搭建

iBatis 的優缺點&#xff1a; 優點&#xff1a; 1、 減少代碼量&#xff0c;簡單&#xff1b; 2、 性能增強&#xff1b; 3、 Sql 語句與程序代碼分離&#xff1b; 4、 增強了移植性&#xff1b; 缺點&#xff1a; 1、 和Hibernate 相比&#xff0c;sql 需要自己寫&#x…

Python | 程序以字符串長度打印單詞

Given a string and we have to split the string into words and also print the length of the each word in Python. 給定一個字符串&#xff0c;我們必須將字符串拆分為單詞&#xff0c;并在Python中打印每個單詞的長度。 Example: 例&#xff1a; Input:str "Hell…

Java——遞歸練習

#練習一&#xff1a;從鍵盤接收一個文件夾路徑&#xff0c;統計該文件夾大小 ###分析&#xff1a; ####每句話相當與每一個要求&#xff0c;每一個要求用一個方法去實現 第一個方法 * getDir()* 第一個要求&#xff1a;從鍵盤接收一個文件夾路徑* 1&#xff0c;創建鍵盤錄入對…

C# 里怎樣得到當前執行的函數名,當前代碼行,源代碼文件名。

得到函數名&#xff1a; System.Diagnostics.StackTrace st new System.Diagnostics.StackTrace(); this.Text st.GetFrame(0).ToString(); 得到代碼行&#xff0c;源代碼文件名&#xff1a; StackTrace st new StackTrace(new StackFrame(true)); Console…

PHP中單引號和雙引號的區別

0x01 單引號 單引號里面的內容不會被解釋&#xff0c;不管什么內容&#xff0c;都當做字符串處理 <?php$abc1234; $stradc$abc; echo $str;輸出 0x02 雙引號 雙引號里面的內容會被解釋&#xff0c;像一些換行&#xff08;\n)、數據元素等都會被解釋 <?php$abc1234;…

Eclipse 代碼提示無效的解決方法

代碼提示一般有兩種形勢1、點提示無效經常打一個點就能調出該對象可選的方法列表。哪天不靈了&#xff0c;可以這樣解決&#xff1a;window->Preferences->Java->Editor->Content Assist->Advanced 上面的選項卡Select the proposal kinds contained in the de…