zoukankan      html  css  js  c++  java
  • 后台计时

     系统中有一个存放压缩文件的临时文件夹。当时间长了后 存放文件多了,占用磁盘空间过大 让费资源, 所以需要定期去清理临时文件夹下的文件。所以最先想到了使用定时器来实现该功能。

    调查:  通过查阅资料  了解到使用Java实现这个功能 有三种方法

    1》使用Quartz  框架   这是一个开源的任务调度框架 

          2》 使用 ScheduledExecutor 实现

          3》 使用 timer 实现

    1、Timer

    Timer myTimer = new Timer();  

            myTimer.schedule(new Worker(), 1000);//1秒后执行  
    //      2012-02-28 09:58:00执行  
            myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"));  
            myTimer.schedule(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次  
    //      2012-02-28 09:58:00执行一次 以后每秒执行一次,如果设定的时间点在当前时间之前,任务会被马上执行,然后开始按照设定的周期定时执行任务  
            myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);  
            myTimer.scheduleAtFixedRate(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次 如果该任务因为某些原因(例如垃圾收集)而延迟执行,那么接下来的任务会尽可能的快速执行,以赶上特定的时间点  
            myTimer.scheduleAtFixedRate(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);//和上个类似  

    timer的缺点:

    (1)Timer对调度的支持是基于绝对时间,而不是相对时间的,由此任务对系统时钟的改变是敏感的;

    (2)所有的TimerTask只有一个线程TimerThread来执行,因此同一时刻只有一个TimerTask在执行;

    (3)Timer线程并不捕获异常,所以任何一个TimerTask的执行异常都会导致Timer终止所有任务;这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。此时,已经被安排但尚未执行的TimerTask永远不会再执行了,新的任务也不能被调度了。


    因此你应该考虑使用ScheduledThreadPoolExecutor作为代替品,ScheduledThreadExecutor只支持相对时间。

    2、ScheduleExecutorService

    ScheduleExecutorService接口中有四个重要的方法,其中scheduleAtFixedRate和scheduleWithFixedDelay在实现定时程序时比较方便。

    (1)scheduleAtFixedRate


    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,  
                long initialDelay,  
                long period,  
                TimeUnit unit);  
    command:执行线程
    initialDelay:初始化延时
    period:两次开始执行最小间隔时间

    unit:计时单位

    (2)scheduleWithFixedDelay

    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,  

                    long initialDelay,  
                    long delay,  
                    TimeUnit unit);  
    command:执行线程
    initialDelay:初始化延时
    period:前一次执行结束到下一次执行开始的间隔时间(间隔执行延迟时间)
    unit:计时单位

    (3)功能示例

    1.按指定频率周期执行某个任务。
    初始化延迟0ms开始执行,每隔100ms重新执行一次任务。

    /** 
     * 以固定周期频率执行任务 
     */  
    public static void executeFixedRate() {  
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);  
        executor.scheduleAtFixedRate(  
                new EchoServer(),  
                0,  
                100,  
                TimeUnit.MILLISECONDS);  
    }  

    间隔指的是连续两次任务开始执行的间隔。

    对于scheduleAtFixedRate方法,当执行任务的时间大于我们指定的间隔时间时,它并不会在指定间隔时开辟一个新的线程并发执行这个任务。而是等待该线程执行完毕。

    2.按指定频率间隔执行某个任务。
    初始化时延时0ms开始执行,本次执行结束后延迟100ms开始下次执行。

    /** 
     * 以固定延迟时间进行执行 
     * 本次任务执行完成后,需要延迟设定的延迟时间,才会执行新的任务 
     */  
    public static void executeFixedDelay() {  
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);  
        executor.scheduleWithFixedDelay(  
                new EchoServer(),  
                0,  
                100,  
                TimeUnit.MILLISECONDS);  

    }  

    间隔指的是连续上次执行完成和下次开始执行之间的间隔。

    3.周期定时执行某个任务。

    有时候我们希望一个任务被安排在凌晨3点(访问较少时)周期性的执行一个比较耗费资源的任务,可以使用下面方法设定每天在固定时间执行一次任务。

    /** 
     * 每天晚上8点执行一次 
     * 每天定时安排任务进行执行 
     */  
    public static void executeEightAtNightPerDay() {  
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);  
        long oneDay = 24 * 60 * 60 * 1000;  
        long initDelay  = getTimeMillis("20:00:00") - System.currentTimeMillis();  
        initDelay = initDelay > 0 ? initDelay : oneDay + initDelay;  
      
        executor.scheduleAtFixedRate(  
                new EchoServer(),  
                initDelay,  
                oneDay,  
                TimeUnit.MILLISECONDS);  
    }  

    /** 
     * 获取指定时间对应的毫秒数 
     * @param time "HH:mm:ss" 
     * @return 
     */  
    private static long getTimeMillis(String time) {  
        try {  
            DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");  
            DateFormat dayFormat = new SimpleDateFormat("yy-MM-dd");  
            Date curDate = dateFormat.parse(dayFormat.format(new Date()) + " " + time);  
            return curDate.getTime();  
        } catch (ParseException e) {  
            e.printStackTrace();  
        }  
        return 0;  
    }  


    3、Spring


    除了我们自己实现定时任务之外,我们可以使用Spring帮我们完成这样的事情。
    Spring自动定时任务配置方法(我们要执行任务的类名为com.study.MyTimedTask)

    <bean id="myTimedTask" class="com.study.MyTimedTask"/>  



    <bean id="doMyTimedTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
        <property name="targetObject" ref="myTimedTask"/>  
        <property name="targetMethod" value="execute"/>  
        <property name="concurrent" value="false"/>  
    </bean>  



    <bean id="myTimedTaskTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
        <property name="jobDetail" ref="doMyTimedTask"/>  
        <property name="cronExpression" value="0 0 2 * ?"/>  
    </bean>  


    <bean id="doScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
        <property name="triggers">  
            <list>  
                <ref local="myTimedTaskTrigger"/>  
            </list>  
        </property>  
    </bean>  



    <bean id="doScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
        <property name="triggers">  
            <list>  
                <bean class="org.springframework.scheduling.quartz.CronTriggerBean">  
                    <property name="jobDetail"/>  
                        <bean id="doMyTimedTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
                            <property name="targetObject">  
                                <bean class="com.study.MyTimedTask"/>  
                            </property>  
                            <property name="targetMethod" value="execute"/>  
                            <property name="concurrent" value="false"/>  
                        </bean>  
                    </property>  
                    <property name="cronExpression" value="0 0 2 * ?"/>  
                </bean>  
            </list>  
        </property>  
    </bean>  

  • 相关阅读:
    Hard Rock
    Codeforces Round #416 (Div. 2) B. Vladik and Complicated Book
    codeforces 793B. Igor and his way to work
    codeforces 1B Spreadsheets
    HDU 1069 Monkey and Banana
    codeforces 2B The least round way
    【机器学习】 通俗说拟合
    python-八皇后问题
    python-核心知识思维导图
    python-@property 属性
  • 原文地址:https://www.cnblogs.com/ouyangping/p/6791759.html
Copyright © 2011-2022 走看看