2013-07-19 70 views
1

我想在將代碼投入生產之前進行確認。阻止隊列,單個生產者 - 多個消費者同步問題

我正在使用LinkedBlockingQueue,如下所示。 我有一個生產者線程和五個消費者線程。 消費者線程執行數據庫操作,所以我已將其增加到5來加快進程。

現在,有沒有什麼辦法可以在代碼或數據庫級別遇到問題(同步/多行更新/我需要注意的任何問題)。

以下是我的完整代碼。

private int numberOfConsumers = 5; 
private LinkedBlockingQueue<RequestParameters> processorQueue; 


public void init(){ 
     processorQueue = new LinkedBlockingQueue<RequestParameters>(); 

     for (int i = 0; i < numberOfConsumers ; i++) { 
      try { 
       QueueConsumer c = new QueueConsumer(processorQueue); 
       c.setName("ThreadName-"+i); 
       c.start(); 

      } catch (Exception e) { 
       logger.error("", e); 
      } 
     } 
     this.postCallProcessorDaemon = this; 
    } 



    class QueueConsumer extends Thread { 
     private Logger log = Logger.getLogger(QueueConsumer.class); 
     private final BlockingQueue<RequestParameters> queue; 
     QueueConsumer(BlockingQueue<RequestParameters> q) { queue = q; } 

     public void run() { 
      try { 
       while (true) { 
        RequestParameters rp = queue.take(); 
        consumeRecord(rp); 
       } 
      } catch (Exception ex) { 
       log.error("Exception in run method", ex); 
      } 
     } 


    void consumeRecord(RequestParameters requestParameters) 
    { 
    try{ 
      process(requestParameters); 
     } catch (Throwable e) { 
      log.error("Exception",e); 
     } 
    } 


    private void process(RequestParameters requestParameters) throws Exception{ 
     for (Action each : allActions) { 
      if(each.doProcessing(requestParameters)){ 
       boolean status = each.process(requestParameters); 
      } 
     } 
    } 

} 


public boolean process(RequestParameters parameters) { 
    //In my process method, I am inserting rows in table based on data in Queue. 
} 

HBM文件,我使用ORM映射

<class name="CampaignSubscriptionsSummary" table="campaign_subscriptions_summary"> 
    <composite-id name="id" class="com.on.robd.config.db.reports.CampaignSubscriptionsSummaryId"> 
     <key-property name="reportTime" type="timestamp"> 
      <column name="REPORT_TIME" length="19" /> 
     </key-property> 
     <key-property name="campaignId" type="long"> 
      <column name="CAMPAIGN_ID" /> 
     </key-property> 
     <key-property name="recipient" type="string"> 
      <column name="RECIPIENT" length="24" /> 
     </key-property> 
     <key-property name="selectedPack" type="string"> 
      <column name="SELECTED_PACK" length="256" /> 
     </key-property> 
    </composite-id> 
    <many-to-one name="campaign" class="com.on.robd.config.db.campaigns.Campaign" update="false" insert="false" fetch="select"> 
     <column name="CAMPAIGN_ID" not-null="true" /> 
    </many-to-one> 
    <many-to-one name="campaignSubscriptionsStatusDim" class="com.on.robd.config.db.reports.CampaignSubscriptionStatusDim" fetch="select"> 
     <column name="SUBSCRIPTION_STATUS_ID" not-null="true" /> 
    </many-to-one> 
    <property name="sender" type="string"> 
     <column name="SENDER" length="24" not-null="true" /> 
    </property> 
    <property name="callDuration" type="java.lang.Integer"> 
     <column name="CALL_DURATION" /> 
    </property> 
    <property name="dtmfInput" type="string"> 
     <column name="DTMF_INPUT" length="16" not-null="true" /> 
    </property> 
    <property name="promptForPack" type="string"> 
     <column name="PROMPT_FOR_PACK" length="256" /> 
    </property> 
    <property name="wavFile" type="string"> 
     <column name="WAV_FILE" length="256" /> 
    </property> 
    <property name="subscriptionUrl" type="string"> 
     <column name="SUBSCRIPTION_URL" length="256" /> 
    </property> 
    <property name="language" type="string"> 
     <column name="LANGUAGE" length="256" /> 
    </property> 
    <property name="reobdTime" type="timestamp"> 
      <column name="REOBD_TIME" length="19" /> 
    </property> 
    <many-to-one name="campaignTypeDim" class="com.on.robd.config.db.reports.CampaignTypeDim" fetch="select"> 
     <column name="CAMPAIGN_TYPE_ID" not-null="true" /> 
    </many-to-one> 
</class> 
+0

我不確定,但它應該是另一種方式。應該有一個人應該在數據庫上操作,並且許多其他人可以要求數據庫操作。 – Reddy

+0

我去了多個消費者,因爲我想確保當我在Queue中獲得一個條目時,那麼很快就會得到處理,然後單個消費者執行該任務,並且隊列中最後一個條目必須等待處理,因爲我的Producer是速度非常快,消費者速度很慢。如果我採取你的方法,那麼事情會再次放緩。 – Jayesh

回答

1

最有可能你就會有消費者之間的DB鎖定的問題,但它取決於你的數據庫供應商。檢查您的數據庫供應商文檔以查看它是否在寫入時使用表格,行或分區鎖定。

但是,無論你會得到更好的寫性能,你使用批量插入。見http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html。最簡單的批處理方法是讓Producer將RequestParameters集合推送到BlockingQueue中。這也可以減少打開連接到數據庫的數量,這也有助於提高性能。

相關問題