2011-09-22 101 views
1

我想在兩個數據庫修訂版上同時運行兩個XPath表達式,這兩個修訂版都返回Iterator/Iterable的結果,並將結果節點與列表中的節點進行匹配。多線程 - 匹配實例

我認爲最好的辦法是從一個ExecutorService運行兩個線程查詢和保存來自兩個線程導致BlockingQueue,而另一個線程將會從BlockingQueue對結果進行排序或實際保存傳入的節點或nodeKeys在正確的位置。

然後是微不足道的獲得所產生的排序列表和其它排序列表的交集。

其他建議?我也可以自由使用任何我喜歡的技術(最好是Java)。番石榴在classpath中,但我已經想過使用演員從阿卡。

編輯:另外一個相關的問題是,如果以流水線的方式使用InsertionSort更快(在收到它們時處理生成的XPath結果),或者等到整個結果生成並使用QuickSort或MergeSort 。我認爲InsertionSort應該是最好的,不管最終的元素數量如何。

一般而言,我希望排序,然後計算兩個列表的交集比搜索XPath結果列表中的每個項目的速度快,即使列表除以可用CPU處理器的數量也會比O(n^2)快。

編輯: 我目前實現的第一部分:

final ExecutorService executor = Executors.newFixedThreadPool(2); 
final AbsTemporalAxis axis = 
    new NextRevisionAxis.Builder(mSession).setRevision(mRevision) 
     .setIncludeSelf(EIncludeSelf.YES).build(); 
for (final IReadTransaction rtx : axis) { 
    final ListenableFuture<Void> future = 
     Futures.makeListenable(executor.submit(new XPathEvaluation(rtx, mQuery))); 
    future.addListener(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       mSemaphore.acquire(); 
      } catch (final InterruptedException e) { 
       LOGWRAPPER.error(e.getMessage(), e); 
      } 
     } 
    }, executor); 
} 
executor.shutdown(); 

final ExecutorService sameThreadExecutor = MoreExecutors.sameThreadExecutor(); 
sameThreadExecutor.submit(new XPathResult()); 
sameThreadExecutor.shutdown(); 
return null; 

信號量被初始化爲2,在XPathEvaluation所得nodeKeys加入到LinkedBlockingQueue

然後我會與評論表示的XPathResults,這還沒有實現排序:

private final class XPathResult implements Callable<Void> { 
    @Override 
    public Void call() throws AbsTTException, InterruptedException { 
     while (true) { 
      final long key = mQueue.take(); 
      if (key == -1L) { 
       break; 
      } 
      if (mSemaphore.availablePermits() == 0) { 
       mQueue.put(-1L); 
      } 

      // Do InsertionSort. 
     } 

     return null; 
    } 
} 

沒有任何的JavaDoc,但我想至少它應該工作,你有什麼感想?你有沒有更好的解決方案,還是我迄今犯過一些錯誤?

親切的問候,
約翰內斯

回答

0

你確定你需要同時做到這一點?你不能只是建立兩個列表連續,之後進行排序的/交叉? - 這將需要複雜的很多從主題。

我認爲相交不能完成,直到兩個列表完全填充,我正確嗎?然後,不需要隊列或同步,只需填寫兩個列表/集合,一旦完成,就會處理完整列表。

但也許我不太明白你的觀點...