SRPING:定时器并发问题

SRPING:定时器并发问题

PUSH_BIRTH_MSG_TEST表status=’1’的数据共19条

SQL>       select ID, USER_ID, STATUS
  2        from PUSH_BIRTH_MSG_TEST
  3        where STATUS = '1'
  4        order by ID
  5      fetch next 50 rows only
  6  /

         ID     USER_ID STATUS
----------- ----------- ------
       6500   928645922 1
       6501   928645922 1
       6502   928645922 1
       6503   928645922 1
       6504   928645922 1
       6505   928645922 1
       6506   928645922 1
       6507   928645922 1
       6508   928645922 1
       6510   928651342 1
       6511   928651342 1
       6512   928651342 1
       6513   928649088 1
       6514   928652889 1
       6515   928652889 1
       6516   928652889 1
       6517   928652889 1
       6519   928652889 1
       6520   928652889 1

19 rows selected

count.txt
SRPING:定时器并发问题_第1张图片

SendSmsBirthJob.java

package com.edai.job;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.edai.service.SendSMSService;

@Component(value = "sendSmsBirth")
public class SendSmsBirthJob {

    @Autowired(required = true)
    private SendSMSService sendSMSService;

    public void executeTask() throws IOException {



        System.out.println("==============================================");
        long start = System.currentTimeMillis();

        File file = new File("c:" + File.separator + "learning" + File.separator + "count.txt");
        InputStream input = null;  
        input = new FileInputStream(file) ;
        byte b[] = new byte[1024]; 
        int len = 0;     
        int line = 0; 
        while((line=input.read())!=-1){    
            b[len] = (byte)line ;    
            len++ ;    
        }    
        input.close() ; 
        String result = new String(b,0,len);
        System.out.println("读取文件: 总共" + result+"条数据。");


        OutputStream output = null;  
        output = new FileOutputStream(file) ;
        List> listMap = sendSMSService.queryAllSms();
        for (int i = 0; i < listMap.size(); i++) {
            Map map = listMap.get(i);
            System.out.println(map.get("ID") + "||" + map.get("USER_ID") + "||" + map.get("STATUS"));
        }
        int listSize = listMap.size();
        result = String.valueOf(Integer.parseInt(result) + listSize);
        System.out.println("count.txt content output: " + result);

        b = result.getBytes();
        output.write(b, 0, b.length);
        output.flush();
        output.close(); 

        try {
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException e) {

        }

        sendSMSService.updateBatchBirthMess();

        long end = System.currentTimeMillis();
        System.out.println("执行时间:"+(end-start)+"毫秒。");

        System.out.println("==============================================");
    }
}

以上逻辑,取得status=1的记录总数,更新到count.txt中。


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    ">
    <description>quartz配置文件description>
    

    
    

    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
        lazy-init="true">
        <property name="triggers">
            <list>
                <ref bean="sendBirthSmsTaskTrigger"/>
            list>
        property>
    bean>

    <bean id="sendBirthSmsTaskTrigger"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail">
            <ref bean="sendBirthSms" />
        property>
        <property name="cronExpression">
            <value>0/1 * * * * ?value>
        property>
    bean>
    <bean id="sendBirthSms"
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="sendSmsBirth" />
        <property name="targetMethod" value="executeTask" />
    bean>
beans>

以上,定时器,0/1 * * * * ?(每秒钟跑一次)
执行结果:

log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/gitworkspaces/springQuartzTest/lib/slf4j-log4j12-1.7.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/gitworkspaces/springQuartzTest/lib/slf4j-simple-1.7.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
==============================================
==============================================
==============================================
==============================================
==============================================
==============================================
6500||928645922||1
6501||928645922||1
6502||928645922||1
6503||928645922||1
6504||928645922||1
6505||928645922||1
6506||928645922||1
6507||928645922||1
6508||928645922||1
6510||928651342||1
6511||928651342||1
6512||928651342||1
6513||928649088||1
6500||928645922||1
6501||928645922||1
6502||928645922||1
6503||928645922||1
6504||928645922||1
6505||928645922||1
6506||928645922||1
6507||928645922||1
6508||928645922||1
6510||928651342||1
6511||928651342||1
6512||928651342||1
6513||928649088||1
6514||928652889||1
6515||928652889||1
6516||928652889||1
6517||928652889||1
6519||928652889||1
6500||928645922||1
6500||928645922||1
6501||928645922||1
6502||928645922||1
6503||928645922||1
6504||928645922||1
6505||928645922||1
6506||928645922||1
6507||928645922||1
6508||928645922||1
6510||928651342||1
6511||928651342||1
6512||928651342||1
6513||928649088||1
6514||928652889||1
6501||928645922||1
6520||928652889||1
6514||928652889||1
6515||928652889||1
6516||928652889||1
6517||928652889||1
6519||928652889||1
6520||928652889||1
6502||928645922||1
6515||928652889||1
6503||928645922||1
6516||928652889||1
6504||928645922||1
6517||928652889||1
6505||928645922||1
6519||928652889||1
6506||928645922||1
6520||928652889||1
6507||928645922||1
6508||928645922||1
count.txt content output: 19
6510||928651342||1
6511||928651342||1
6512||928651342||1
6513||928649088||1
6514||928652889||1
6515||928652889||1
6516||928652889||1
6517||928652889||1
6519||928652889||1
6520||928652889||1
6500||928645922||1
6501||928645922||1
6502||928645922||1
6503||928645922||1
6504||928645922||1
6505||928645922||1
6506||928645922||1
6507||928645922||1
6508||928645922||1
6510||928651342||1
6511||928651342||1
6512||928651342||1
6513||928649088||1
6514||928652889||1
6515||928652889||1
6516||928652889||1
6517||928652889||1
6519||928652889||1
6520||928652889||1
==============================================
6500||928645922||1
6501||928645922||1
6502||928645922||1
6503||928645922||1
6504||928645922||1
6505||928645922||1
6506||928645922||1
6507||928645922||1
6508||928645922||1
6510||928651342||1
6511||928651342||1
6512||928651342||1
6513||928649088||1
6514||928652889||1
6515||928652889||1
6516||928652889||1
6517||928652889||1
6519||928652889||1
6520||928652889||1
count.txt content output: 38
执行时间:5420毫秒,总共更更新了19条数据。
==============================================
==============================================
count.txt content output: 38
执行时间:1095毫秒,总共更更新了38条数据。
==============================================
==============================================
count.txt content output: 38
执行时间:1047毫秒,总共更更新了38条数据。
==============================================
==============================================
count.txt content output: 38
执行时间:1055毫秒,总共更更新了38条数据。
==============================================
==============================================
count.txt content output: 38
执行时间:1100毫秒,总共更更新了38条数据。
==============================================
==============================================
count.txt content output: 38
执行时间:1055毫秒,总共更更新了38条数据。
==============================================
==============================================
count.txt content output: 38
执行时间:1024毫秒,总共更更新了38条数据。
==============================================

SRPING:定时器并发问题_第2张图片

结果说明:
应该是抽取状态为1的19条记录,更新19条记录的状态成2,19记录到count.txt,下一次抽取状态为1的记录为0条,count.txt最终还是19。
而以上定时器每秒执行一次,代码逻辑中休眠1秒后再更新状态,所以每次执行超过1秒还没有把状态为1的19条数据更新成2,更新还没有commit完毕,19条记录的状态仍然为1,第二次的任务又开启,再次取得了状态为1的19条数据,导致并发,count.txt变成了38。

解决方案:

    id="sendBirthSms"
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="sendSmsBirth" />
        <property name="targetMethod" value="executeTask" />
        <property name="concurrent" value="false" />
    

定时器配置文件,默认为true,不添加会存在并发问题,添加后,一次任务执行完毕之后才会再执行第二次任务,以上每秒执行一次,每次的任务执行超过1秒,均是等该任务执行完毕,才执行下一次的任务。
添加后,运行结果如下:

log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/gitworkspaces/springQuartzTest/lib/slf4j-log4j12-1.7.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/gitworkspaces/springQuartzTest/lib/slf4j-simple-1.7.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
==============================================
6500||928645922||1
6501||928645922||1
6502||928645922||1
6503||928645922||1
6504||928645922||1
6505||928645922||1
6506||928645922||1
6507||928645922||1
6508||928645922||1
6510||928651342||1
6511||928651342||1
6512||928651342||1
6513||928649088||1
6514||928652889||1
6515||928652889||1
6516||928652889||1
6517||928652889||1
6519||928652889||1
6520||928652889||1
count.txt content output: 19
执行时间:1967毫秒,总共更更新了19条数据。
==============================================
==============================================
count.txt content output: 19
执行时间:1049毫秒,总共更更新了19条数据。
==============================================
==============================================
count.txt content output: 19
执行时间:1021毫秒,总共更更新了19条数据。
==============================================
==============================================
count.txt content output: 19
执行时间:1024毫秒,总共更更新了19条数据。
==============================================
==============================================
count.txt content output: 19
执行时间:1035毫秒,总共更更新了19条数据。
==============================================
==============================================

你可能感兴趣的:(并发,并发)