阻止队列,单一生产者 - 多个消费者同步问题

时间:2013-07-19 07:07:05

标签: java spring hibernate java-ee queue

我想在将代码投入生产之前确认。

我正在使用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.
}

我用于ORM映射的HBM文件

<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>

1 个答案:

答案 0 :(得分:1)

很可能您会在消费者之间遇到数据库锁定问题,但这取决于您的数据库供应商。检查数据库供应商文档,看它是否在写入时使用表,行或分区锁定。

但是无论你使用批量插入还是会有更好的写入性能。见http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html。最简单的批处理方法是让Producer将一组RequestParameters推送到BlockingQueue中。这也可以减少您对数据库的开放连接数量,这也有助于提高性能。