精华内容
下载资源
问答
  • 每天执行一次: package com.guomo.app.utils; import cn.hutool.http.HttpRequest; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import ...

    一:

    每天执行一次:

    package com.guomo.app.utils;
    
    import cn.hutool.http.HttpRequest;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.guomo.app.entity.vo.GreentimeVo;
    
    import javax.servlet.ServletContextListener;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    
    //定时器
    public class DayInterval implements ServletContextListener {
    
    
    
    
        public static void showDayTime() {
    
            Calendar calendar = Calendar.getInstance();
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH);
            int day = calendar.get(Calendar.DAY_OF_MONTH);
    
            calendar.set(year, month, day, 15, 40, 00);//设置要执行的日期时间
    
            Date defaultdate = calendar.getTime();
    
            Timer dTimer = new Timer();
            dTimer.schedule(new TimerTask() {
    
    
    
        @Override
        public void run() {
            System.out.println("每日任务已经执行");
    
            
    
    
                }
    
                }, defaultdate , 24* 60* 60 * 1000);//24* 60* 60 * 1000
        }
    
        public static void main(String[] args) {
            showDayTime();
    
    
        }
    
    }
    
    

    每隔多久执行一次:

    package com.guomo.app.utils;
    
    //调用的工具
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    public class Task3 {
        public static void main(String[] args) {
            /**
             * Runnable:实现了Runnable接口,jdk就知道这个类是一个线程
             */
            Runnable runnable = new Runnable() {
                //创建 run 方法
                public void run() {
                    // task to run goes here
                    System.out.println("Hello, stranger");
                }
            };
            // ScheduledExecutorService:是从Java SE5的java.util.concurrent里,
            // 做为并发工具类被引进的,这是最理想的定时任务实现方式。
            ScheduledExecutorService service = Executors
                    .newSingleThreadScheduledExecutor();
            // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
            // 10:秒   5:秒
            // 第一次执行的时间为10秒,然后每隔五秒执行一次
            service.scheduleAtFixedRate(runnable, 10, 5, TimeUnit.SECONDS);
        }
    }
    
    

    二:

    Springboot中有**@EnableScheduling**注解可以做到开启服务器后通过Springboot整合Schedule来实现一个定时任务。

    @SpringBootApplication
    //添加下面这个注解
    @EnableScheduling
    public class AppApplication{
        public static void main(String[] args) {
            AppApplication.run(AppApplication.class, args);
        }
    }
    

    启动的时候一旦扫描到就@Component标志有定时任务存在,就会执行定时任务。

    @Component
     public class MyScheduledTask {
         @Scheduled(cron = "5 0 0 * * ?")
         public void scheduledTask1(){
             System.out.println("定时任务1");
         }
     
         @Scheduled(initialDelay =  1000 * 10,fixedDelay = 1000 * 5)
         public void scheduledTask2(){
            System.out.println("任务2执行");
        }
        @Scheduled(initialDelay =  1000 * 10,fixedRate = 1000 * 5)
        public void scheduledTask3(){
            System.out.println("任务3执行时间:"+System.currentTimeMillis()%10000);
            try {
                Thread.sleep(2*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务3结束时间:"+System.currentTimeMillis()%10000);
        }
    }
    

    定时参数:

    Cron:

    Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:

    (1) Seconds Minutes Hours DayofMonth Month DayofWeek Year

    (2)Seconds Minutes Hours DayofMonth Month DayofWeek

    字段允许值允许的特殊字符
    秒(Seconds)0~59的整数, - * / 四个字符
    分(Minutes)0~59的整数, - * / 四个字符
    小时(Hours)0~23的整数, - * / 四个字符
    日期(DayofMonth)1~31的整数,- * ? / L W C 八个字符
    月份(Month)1~12的整数或者 JAN-DEC, - * / 四个字符
    星期(DayofWeek)1~7的整数或者 SUN-SAT (1=SUN), - * ? / L C # 八个字符
    年(可选,留空)(Year)1970~2099, - * / 四个字符
    解释:

    (1) * 表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都会触发事件。

    (2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但是有种情况例外。如写法:13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发。

    (3)-:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次 。

    (4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.

    (5),:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。

    (6)L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。

    (7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。

    (8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。

    (9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

    2、其他参数

    (1)initialDelay:启动后多久开始执行,单位时毫秒

    (2)fixedRate:下次执行时间,任务开始运行的时候就计时。

    (3)fixedDelay:下次执行时间,fixedDelay等任务进行完了才开始计时

    以下是网上摘抄的部分例子说明:

    一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。
    corn表达式格式:
    秒 分 时 日 月 周 年(可选)。
    “?”字符:表示不确定的值
    “,”字符:指定数个值
    “-”字符:指定一个值的范围
    “/”字符:指定一个值的增加幅度。n/m表示从n开始,每次增加m
    “L”字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期X
    “W”字符:指定离给定日期最近的工作日(周一到周五)
    “#”字符:表示该月第几个周X。6#3表示该月第3个周五

    例子:
    每隔5秒执行一次:/5 * * * ?
    每隔1分钟执行一次:0 /1 * * ?
    每天23点执行一次:0 0 23 * * ?
    每天凌晨1点执行一次:0 0 1 * * ?
    每月1号凌晨1点执行一次:0 0 1 1 * ?
    每月最后一天23点执行一次:0 0 23 L * ?
    每周星期天凌晨1点实行一次:0 0 1 ? * L
    在26分、29分、33分执行一次:0 26,29,33 * * * ?
    每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?
    每天的8点开始,2小时执行一次:0 0 8/2 * * ?

    展开全文
  • 需求:在tomcat中,每月一号、每日、每分钟自动执行指定的任务。 开发环境: java + tomcat 实现思路:在tomcat中,添加监听器,在监听器中设置定时任务。 1.监听: 新建监听:新建类,implents ...

    需求:在tomcat中,每月一号、每日、每分钟自动执行指定的任务。

    开发环境: java + tomcat

    实现思路:在tomcat中,添加监听器,在监听器中设置定时任务。

    1.监听:

    新建监听:新建类,implents ServletContextListener 即可:

    讲解:

    1.1创建一个基准时间(每日8点),用于参照。在此时间以后的多长周期内执行操作。

    1.2 schedule(task, firstTime, period); 方法参数:

    task:TimerTask任务,用内部匿名类的方式新建一个即可(当然也可以在外部类中建一个类,用于写任务,写法麻烦点),实现run()方法,在Run中写你要执行操作即可。

    firstTime:放建好的基准时间

    period:执行周期,单位:毫秒。一天写法:24 * 60 * 60 * 1000

    1.3 : 如何判断是每月1号?用Calendar的Calendar.DAY_OF_MONTH,每月首天返回值为1。每天都执行下判断,到每月一号时,即可实现每月执行一次

    Web监听器代码如下:

    1.4

    package com.today.ems.listener;
     
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
     
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
     
    import org.apache.log4j.Logger;
     
    import com.today.ems.client.TemsWsClient;
     
    public class SendWsListener implements ServletContextListener {
    	private final static Logger logger = Logger.getLogger(SendWsListener.class);
     
    	@Override
    	public void contextDestroyed(ServletContextEvent arg0) {
    		logger.debug("定时发送Xml信息监听--已关闭!");
    	}
     
    	@Override
    	public void contextInitialized(ServletContextEvent arg0) {
    		// 指定的任务,从指定的延迟后,开始进行重复执行。
    		Calendar calendar = Calendar.getInstance();
    		int year = calendar.get(Calendar.YEAR);
    		int month = calendar.get(Calendar.MONTH);
    		int day = calendar.get(Calendar.DAY_OF_MONTH);
    		/**
    		 *  定制每天的8:00:00执行,若程序已超过8点启动,当天不再执行,等到明日八点再执行
    		 *  这样保证了时间一直是8点,而不会变成程序启动时间
    		 */
    		calendar.set(year, month, day, 8, 00, 00);
    		Date defaultdate = calendar.getTime();// 今天8点(默认发送时间)
    		Date sendDate = new Date();
    		// 8点后开机
    		if (defaultdate.before(new Date())) {
    			// 将发送时间设为明天8点
    			calendar.add(Calendar.DATE, 1);
    			sendDate = calendar.getTime();
    		}
    		
    		/**
    		 * ----------------每刻任务 ----------------
    		 * 启动服务器后,若此时时间没过8点,等待。到了8点自动执行一次,15分钟后再执行一次,周而复始
    		 * 启动服务器后,若此时时间超过8点,会立刻执行一次,等到15分钟后再次执行一次,周而复始
    		 * 到了第二天,不会再判断是否是8点,这个开始时间,只会判断一次而已
    		 */
    		Timer qTimer = new Timer();
    		qTimer.schedule(new TimerTask() {
     
    			@Override
    			public void run() {
    				logger.info("每刻任务已执行");
    				TemsWsClient client = new TemsWsClient();
    				client.sendXmlData(client.getBeanIdsNow());
    			}
    		}, defaultdate, 15 * 60 * 1000);// 定时每15分钟
    		logger.debug("每刻定时发送Xml信息监听--已启动!");
     
    		/**
    		 * ----------------每日任务 ----------------
    		 * 启动服务器后,若此时时间没过8点,等待。到了8点自动执行一次,24小时后(第二天8点)再执行一次,周而复始
    		 * 启动服务器后,若此时时间已经超过8点,会立刻执行一次,等到24小时后(第二天8点)再次执行一次,周而复始
    		 */
    		Timer dTimer = new Timer();
    		dTimer.schedule(new TimerTask() {
     
    			@Override
    			public void run() {
    				logger.info("每日任务已经执行");
    				TemsWsClient client = new TemsWsClient();
    				client.sendXmlData(client.getBeanIdsDay());
    			}
    		}, sendDate, 24 * 60 * 60 * 1000);// 定时24小时:24 * 60 * 60 * 1000
    		logger.debug("每日定时发送Xml信息监听--已启动!");
     
    		/**
    		 * ----------------每月任务 ----------------
    		 * 启动服务器后,若此时时间没过8点,等待。到了8点自动执行判断是否是当前月份的1号,若是则执行一次,
    		 * 24小时后(第二天8点)再执行一次判断(每月1号以后后的29天或30天后才会是下月1号,再执行一次),周而复始
    		 * 启动服务器后,若此时时间已经超过8点,会立刻执行一次,等到下个月1号再次执行一次,周而复始
    		 */
    		Timer mTimer = new Timer();
    		mTimer.schedule(new TimerTask() {
     
    			@Override
    			public void run() {
    				Calendar c = Calendar.getInstance();
    				int day = c.get(Calendar.DAY_OF_MONTH);
    				logger.info("月任务 判断中");
    				if (day == 1) {
    					// 每天执行,若为每月1号才执行
    					logger.info("月任务执行已执行");
    					TemsWsClient client = new TemsWsClient();
    					client.sendXmlData(client.getBeanIdsMon());
    				}
     
    			}
    		}, sendDate, 24 * 60 * 60 * 1000);// 每天执行一次检查
     
    		logger.debug("每月定时发送Xml信息监听--已启动!");
     
    	}
     
    }
    
    

    2.在web.xml中设置监听文件:

    <web-app>  
      <listener>
        <listener-class>com.today.ems.listener.SendWsListener</listener-class>
      </listener>
    </web-app>
    
    

    3.重新部署项目,启动tomcat即可自动执行。

    展开全文
  • 因为需要,我在代码中写了一个程序一秒调度一次执行一些不是很短的任务,但是具体耗时不知道,但是这个服务在现场出问题了,然后代码审核的时候,觉得这里一次速度太快了。会不会出现一个还没执行完毕。另外一...

    在这里插入图片描述

    1.概述

    因为需要,我在代码中写了一个程序一秒调度一次,执行一些不是很短的任务,但是具体耗时不知道,但是这个服务在现场出问题了,然后代码审核的时候,觉得这里每秒一次速度太快了。会不会出现一个还没执行完毕。另外一个调度又开始了?然后现场叠加了,导致内存中很多线程。

    我于是做了个实验

    package com.java.thread.demo.schedule;
    
    import java.util.concurrent.Executors
    展开全文
  • 本人遇见问题不是web.xml中加载两applicationContext导致的各bean加载两,而是在tomcat中server.xml中Host的appBase为webapps,在context中又加载了。把appBase设为“”好使;另外,从网上看到把Host的节点的...

    本人遇见问题不是web.xml中加载两次applicationContext导致的各bean加载两次,而是在tomcat中server.xml中Host的appBase为webapps,在context中又加载了。把appBase设为“”好使;另外,从网上看到把Host的节点的autoDeploy unpackWARs还有reloadable都致为false也可行,还有一种不加context也是可行的。

    另外就是判断是否重复执行定时任务:https://blog.csdn.net/caomiao2006/article/details/51338254;这个没有试过,待尝试。

    分别如下:

    一:这种方法不会在webapps下解压出对应文件,在work/Catalina/localhost/-下,有对应项目执行class等

    <Host name="localhost"  appBase=""
                unpackWARs="true" autoDeploy="true">
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log." suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
            <Context docBase="webapps/xxx" path=""  reloadable="true" ></Context>
          </Host>

    二:去掉Context标签,显示完整,会解压war包,但是不能定义访问路径和指定多项目。

    <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true">
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log." suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
           
          </Host>

     

    转自:https://blog.csdn.net/bbj12345678/article/details/78530428

    今天在做一个项目的时候用到了Spring的定时计划任务。这是Spring的特色功能,可以根据设置在特定的时间或间隔时间做特定的事。

    下面给出一个例子:

     

    [java] view plain copy

    1. package net.csdn.blog.chaijunkukn;  
    2.   
    3. import java.text.SimpleDateFormat;  
    4. import java.util.Calendar;  
    5. import java.util.Locale;  
    6.   
    7. public class TimerTask {  
    8.     public void printTimeStamp(){  
    9.         Calendar ca= Calendar.getInstance();  
    10.         ca.setTimeInMillis(System.currentTimeMillis());  
    11.         SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS ", Locale.CHINA);  
    12.         //显示当前时间 精确到毫秒  
    13.         System.out.print(sdf.format(ca.getTime()));       
    14.     }  
    15.     public TimerTask(){  
    16.         this.printTimeStamp();  
    17.         System.out.println("计划任务被初始化了");  
    18.     }  
    19.     public void doTask(){  
    20.         this.printTimeStamp();        
    21.         System.out.print("计划任务被执行,线程id:");  
    22.         System.out.println(Thread.currentThread().getId());  
    23.     }  
    24. }  

     

    根据Spring关于定时任务的规范,任务执行方法应为无参数无返回的方法,因此按照规范上面的例子中声明了doTask方法。上面的例子很简单,Spring作为IoC容器,构造TimerTask实例时会调用无参构造函数,此类会在实例化时在控制台输出当前时间和构造信息。当定时任务被触发时,也会在控制台显示当前时间和任务被执行的提示信息。

    下面是配置(需要声明的是,本实例基于J2EE工程,使用了log4j,配置文件只是工程中的一部分): 

     

    [java] view plain copy

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
    5.        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">  
    6.     <!-- 注册定时器 -->  
    7.     <bean id="timer"  
    8.         class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
    9.         <property name="triggers">  
    10.             <list>  
    11.                 <ref bean="timerTaskTrigger" />  
    12.             </list>  
    13.         </property>  
    14.     </bean>  
    15.     <!-- 指定何时触发定时任务 -->  
    16.     <bean id="timerTaskTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
    17.         <property name="jobDetail">  
    18.             <ref bean="timerTaskJobDetail" />  
    19.         </property>  
    20.         <property name="cronExpression">  
    21.             <!-- 每3秒钟触发一次 -->  
    22.             <value>0/3 * * * * ?</value>  
    23.         </property>  
    24.     </bean>  
    25.     <!-- 指定定时任务细节 调用哪个类 哪个方法 -->  
    26.     <bean id="timerTaskJobDetail"  
    27.         class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
    28.         <property name="targetObject">  
    29.             <ref bean="timerTaskInstance" />  
    30.         </property>  
    31.         <property name="targetMethod">  
    32.             <value>doTask</value>  
    33.         </property>  
    34.         <property name="concurrent" value="false" />  
    35.     </bean>  
    36.     <!-- 实例化定时任务类 -->  
    37.     <bean id="timerTaskInstance" class="net.csdn.blog.chaijunkukn.TimerTask" />  
    38. </beans>  


    web.xml的配置: 

     

     

     

    [java] view plain copy

    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <web-app id="WebApp_ID" version="2.4"  
    3.     xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    4.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
    5.     <display-name>TaskTest</display-name>  
    6.     <servlet>  
    7.         <servlet-name>springapp</servlet-name>  
    8.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    9.         <init-param>  
    10.             <param-name>contextConfigLocation</param-name>  
    11.             <param-value>/WEB-INF/classes/applicationContext*.xml</param-value>  
    12.         </init-param>  
    13.         <load-on-startup>1</load-on-startup>  
    14.     </servlet>  
    15.   
    16.     <servlet-mapping>  
    17.         <servlet-name>springapp</servlet-name>  
    18.         <url-pattern>*.htm</url-pattern>  
    19.     </servlet-mapping>  
    20.   
    21.     <filter>  
    22.         <filter-name>EncodingFilter</filter-name>  
    23.         <filter-class>com.ku6.tech.wap.filter.EncodingFilter</filter-class>  
    24.         <init-param>  
    25.             <param-name>encoding</param-name>  
    26.             <param-value>utf-8</param-value>  
    27.         </init-param>  
    28.         <init-param>  
    29.             <param-name>forceEncoding</param-name>  
    30.             <param-value>true</param-value>  
    31.         </init-param>  
    32.     </filter>  
    33.       
    34.     <filter-mapping>  
    35.         <filter-name>EncodingFilter</filter-name>  
    36.         <url-pattern>*.htm</url-pattern>  
    37.     </filter-mapping>  
    38.   
    39.     <error-page>  
    40.         <error-code>404</error-code>  
    41.         <location>/error.jsp</location>  
    42.     </error-page>  
    43.   
    44.     <welcome-file-list>  
    45.         <welcome-file>index.jsp</welcome-file>  
    46.     </welcome-file-list>  
    47.   
    48.     <listener>  
    49.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    50.     </listener>  
    51.   
    52.     <context-param>  
    53.         <param-name>contextConfigLocation</param-name>  
    54.         <param-value>/WEB-INF/classes/applicationContext*.xml</param-value>  
    55.     </context-param>  
    56. </web-app>  

     

     

    配置的部分就是这样,然后我使用MyEclipse 9.1关联上Tomcat服务器。一切都是默认的设置,然后将本引用部署并启动Tomcat服务器。

    这时候问题来了,我的任务类居然被创建了两次,下面是截取的部分日志数据:

     

     

    [java] view plain copy

    1. 2011-11-01 19:09:02,568 INFO [main] - org.springframework.orm.hibernate3.HibernateTransactionManager.afterPropertiesSet(421) | Using DataSource [org.apache.commons.dbcp.BasicDataSource@f2ff9b] of Hibernate SessionFactory for HibernateTransactionManager  
    2. 2011-11-01 19:09:02,756 INFO [main] - org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer.postProcessTemplateLoaders(124) | ClassTemplateLoader for Spring macros added to FreeMarker configuration  
    3. 2011-11-01 19:09:03.878 计划任务被初始化了  
    4. 2011-11-01 19:09:03,987 INFO [main] - org.quartz.core.SchedulerSignalerImpl.<init>(63) | Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl  
    5. 2011-11-01 19:09:03,987 INFO [main] - org.quartz.core.QuartzScheduler.<init>(214) | Quartz Scheduler v.1.6.1-RC1 created.  
    6. ...  
    7. 2011-11-01 19:09:05,140 WARN [main] - org.hibernate.cache.EhCacheProvider.buildCache(86) | Could not find configuration [org.hibernate.cache.StandardQueryCache]; using defaults.  
    8. 2011-11-01 19:09:05,218 INFO [main] - org.springframework.orm.hibernate3.HibernateTransactionManager.afterPropertiesSet(421) | Using DataSource [org.apache.commons.dbcp.BasicDataSource@85b4c5] of Hibernate SessionFactory for HibernateTransactionManager  
    9. 2011-11-01 19:09:05,218 INFO [main] - org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer.postProcessTemplateLoaders(124) | ClassTemplateLoader for Spring macros added to FreeMarker configuration  
    10. 2011-11-01 19:09:05.249 计划任务被初始化了  
    11. 2011-11-01 19:09:05,249 INFO [main] - org.quartz.core.SchedulerSignalerImpl.<init>(63) | Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl  
    12. 2011-11-01 19:09:05,249 INFO [main] - org.quartz.core.QuartzScheduler.<init>(214) | Quartz Scheduler v.1.6.1-RC1 created.  
    13. ...  
    14. 2011-11-1 19:09:05 org.apache.catalina.startup.Catalina start  
    15. 信息: Server startup in 9451 ms  
    16. 2011-11-01 19:09:06.013 计划任务被执行,线程id:17  
    17. 2011-11-01 19:09:06.013 计划任务被执行,线程id:39  
    18. 2011-11-01 19:09:09.021 计划任务被执行,线程id:19  
    19. 2011-11-01 19:09:09.021 计划任务被执行,线程id:40  


    从上面的日志中可以看出,

     

    在2011-11-01 19:09:03.878 定时计划任务类产生了一个实例 

    在2011-11-01 19:09:05.249 定时 计划任务类又产生了一个实例

    起初我对它并不关心,但是下面的问题却是不可接受的,计划任务确实是差不多每隔3秒钟被调度的,但是每次调度执行了任务方法两次。设想一下,这仅仅是个开销很小的例子,但是如果这个方法执行的是一个非常耗时耗资源的任务,好不容易执行完一次后又要执行一次,这是对计算资源的极大浪费。于是查找了一天的原因,最后在国外的一个论坛上找到了解决的办法(http://forum.springsource.org/showthread.php?33311-IoC-Container-initializes-my-app-twice)。

     

    楼主roncox和我遇到了同样的问题,他和我的配置差不多,同样也贴出了配置文件。虽然其他人没有解决问题,但是他自己解决了,并提供了最后的解决方法:

     

    解决办法就是将web.xml配置文件中的如下节点删掉:

     

    [html] view plain copy

    1. <listener>  
    2.     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    3. </listener>  
    4.   
    5. <context-param>  
    6.     <param-name>contextConfigLocation</param-name>  
    7.     <param-value>/WEB-INF/classes/applicationContext*.xml</param-value>  
    8. </context-param>  


    修改之后程序运行一切正常。个人推测,由于org.springframework.web.context.ContextLoaderListener和org.springframework.web.servlet.DispatcherServlet都能够加载applicationContext*.xml(“*”是通配符,表示所有以“applicationContext”开头的xml文件)。而两个类殊途同归,最终都将这些配置文件交给了Spring框架的Ioc容器进行实例化。因此每个类都会被实例化两次。

     

     

    2012年1月10日补充:今天做项目自习研究了一下spring的配置文件,发现之前说的不完全正确,不应该删除web.xml中的如下节点

     

    [html] view plain copy

    1. <listener>  
    2.     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    3. </listener>  
    4.   
    5. <context-param>  
    6.     <param-name>contextConfigLocation</param-name>  
    7.     <param-value>/WEB-INF/classes/applicationContext*.xml</param-value>  
    8. </context-param>  


    因为该节点指派的applicationContext*.xml是用于实例化除servlet之外的所有对象的,可以说项目中绝大多数的service和dao层操作都由ContextLoaderListener传递给Spring来进行实例化。

     

    在web应用中,web.xml还经常出现如下的配置:

     

    [html] view plain copy

    1. <!--全局Servlet调度配置 -->  
    2.     <servlet>  
    3.         <!--若设置 servlet-name为[name] -->  
    4.         <!--则DispatcherServlet在实例化后会自动加载[name]-servlet.xml -->  
    5.         <servlet-name>spring</servlet-name>  
    6.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    7.         <init-param>  
    8.             <param-name>contextConfigLocation</param-name>  
    9.             <param-value>classpath:servletContext.xml</param-value>  
    10.         </init-param>  
    11.         <!--随服务器一同启动 -->  
    12.         <load-on-startup>1</load-on-startup>  
    13.     </servlet>  
    14.     <servlet-mapping>  
    15.         <servlet-name>spring</servlet-name>  
    16.         <url-pattern>*.do</url-pattern>  
    17.     </servlet-mapping>  


    这个是用来处理所有servlet的,没有它就无法通过请求地址来调用相应的Controller。
    这里我明确地指示了要加载类路径下的servletContext.xml,如果不指定,则会按照注释中所描述地那样自动加载spring-servlet.xml
    无论是servletContext.xml还是applicationContext*.xml都可以按照<beans>...<bean id="XXX" class="XXX" />...</beans>这样的形式来配置。
    问题来了,有时候不注重对象初始化的分类,尤其是使用<context:component-scan base-package="controller" />这样的包扫描形式统一初始化,
    很容易造成满足条件的对象被初始化两次,那么在计划任务的时候被执行两次也就不奇怪了。其实说来说去,还是要提醒大家,不同的配置文件其作用是不一样的,
    不要将所有的初始化操作都放到一个配置文件中,更不要重复配置。不仅浪费资源,还很容易导致莫名其妙的故障。

     

     

    另外,有相关文章还提到过是Tomcat服务器的问题,修改conf目录下的server.xml。修改节点Host,将appBase属性由默认的“webapps”设置为空("")即可,如下所示:

     

     

    [html] view plain copy

    1. <Host name="localhost" appBase="" unpackWARs="true" autoDeploy="true"  
    2.     xmlValidation="false" xmlNamespaceAware="false">  
    3.   
    4.     <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/semwinner"  
    5.         path="" reloadable="true"></Context>  
    6.     <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/emarboxmanager"  
    7.         path="/admin" reloadable="true"></Context>  
    8. </Host>    

     

     

    但是本人尝试之后并没有起作用。可能不适用于我遇到的这个问题。写出上面解决方法的作者认为web应用程序默认都是放在webapps这个目录下的,如果不把“webapps“去掉,这里会调用一次quartz的任务调度,在接下来的“<Context path”中又会调用一次quartz的任务调度,所以就重复了2次。两个方法都写出来,供朋友们参考。

    第二种解决方法来自http://nkliuliu.iteye.com/blog/816335

     

    [html] view plain copy

    1. <listener>  
    2. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    3. </listener>  
    4. <context-param>  
    5. <param-name>contextConfigLocation</param-name>  
    6. <param-value>classpath:applicationContext*.xml</param-value>  
    7. </context-param>  
    8. <servlet>  
    9. <servlet-name>spring</servlet-name>  
    10. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    11. <init-param>  
    12. <param-name>contextConfigLocation</param-name>  
    13. <param-value>classpath:spring-servlet.xml</param-value>  
    14. </init-param>  
    15. <load-on-startup>1</load-on-startup>  
    16. </servlet>  


    listener--context-param这段配置是负责依赖注入的,配置文件名称支持正则匹配。这里是关键,你要看看所有匹配规则的配置文件中是否存在重复注入bean的现象;
    servlet这段是负责请求URL请求处理转发到哪个Bean上的。
    希望对你有帮助。

     

     

    关键:spring-servlet.xml 文件负责的是url 的转发,而 applicationContext.xml 负责的是bean 的注入,两者负责的工作不一样,所以在 web.xml 文件中配置的时候,就需要注意,DispatcherServlet 的初始化参数是spring-servlet.xml,而ContextLoaderListener的初始化参数才是applicationContext.xml 文件呢。

     

     

    经过本人测试发现第二种:修改 server.xml 文件的方式是可以的,反而第一种方式不起作用。

    展开全文
  • 最近遇到问题,需要写个程序段时间去检测数据库超时的query,然后杀掉该query的进程。用到了Java自带的定时器。 Timer用法 delay和period都是long类型的延迟时间, 单位为毫秒 timer.schedule(task, time);...
  • 常见的几种方法: 1.@Scheduled注解:基于注解 使用注解@Scheduled标记目标方法,参数为执行时间 ...4.quartz配置定时器:基于spring的quartz框架 优缺点: 1.@schedule使用方便快捷,但功能有限,扩展性极低,适用
  • //执行时间 private static Integer cacheTime = 14400000; //延迟时间 private static Integer delay = 1000; Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { //c
  • java实现一秒钟执行一次方法

    万次阅读 2018-01-23 14:29:08
    java实现一秒钟执行一次方法 首先写想要执行的方法,写完方法后加上相应的注解,我是在spring的配置文件中加的注解,如下:   我是把方法写在controller里,注意方法里不要加参数,不然会报错,也...
  • 如果你懒,请下载!springmvc中实现quartz定时任务(每分钟的第3秒执行任务调度方法)文章代码!
  • java2分钟执行一下方法

    千次阅读 2019-08-11 16:11:17
    import java.util.Calendar; import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class TimerTest { public static void main(String[] args) { Calendar cal...
  • java定时器-固定时间间隔内执行操作

    千次阅读 2017-10-25 11:27:08
    java实现定时器操作
  • java每隔15分钟获取一次时间

    千次阅读 2019-09-09 19:39:16
    隔15分钟获取一次时间,使用string串展示 public static void getEleccode() { int a=0; String key=""; String value=""; for(int i=0;i<96;i=i+4) { String flag="00"; for(int j=0;j...
  • 在应用开发中,经常需要一些周期性的操作,比如5分钟执行某一...可安排任务执行一次或者定期重复执行.其中几个方法需要我们注意一下:  cancel():终止此计时器,丢弃所有当前已安排的任务。  schedule(TimerTa
  • 问题描述:最近同事因为业务... , 本来目的是想 每五分钟执行一次,经过看系统日志及分析该表达式可以得出:一到执行时间就每秒执行一次 备注:*:表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都...
  • 线程(死循环)执行后等待 使用计时器控制 5s后唤醒,重复执行 public class Test { public static void main(String[] args) { Lock lock=new Lock();//创建锁对象 //实现runnable接口,实现runnable方法 ...
  • Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。 具体实现如下: 1 package com.aone.foottalk.common; 2 3 ...
  • 一、创建存放shell脚本的文件夹 ...举例:5分钟执行一次   */5 * * * * /bin/bash /data/shell/getdata.sh >/dev/null 2>&1   八、查看是否添加进去 [root@ shell ]# crontab -l 
  • java定时器类为java.util.Timer,个定时器可以执行多个定时任务,个定时任务就是个线程,这个类是线程安全的,即多个线程可以无需进行外部同步共享单个Timer对象 任务类为java.util.TimerTask,任务由定时器...
  • 定时器顾名思义,即定时触发某个事件,分离开来,即包含三个因素:定时,触发,某个事件,本文也将以此为基础介绍五种常见的定时器 本文只做基于SpringBoot的示例,其余版本的请自行查阅资料,大同小异 1.介绍 1.1...
  • 我首先接触到的定时器就是根据线程的Thread.sleep()方法实现的,最开始学习java的时候,会用这个方法实现一些简单的动画效果,今天就来回顾一下当初的小动画! 1. 利用Thread.sleep();方法实现定时任务 首先 ...
  •   阅读目录 、概念 二、Timer类注意事项 三、scheduleAtFixedRate(TimerTask task,Date firstTime,long period) 和 schedule(TimerTask task,Date firstTime,lo...
  • <cron-expression>0 0/30 * * * ?...:隔30分钟<cron-expression>0 0/15 * * * ?</cron-expression>隔15分钟<cron-expression>0 0 0/1 * * ?</cron-expression>...
  • package com.demo4; import java.util.TimerTask; public class Task extends TimerTask{ @Override public void run() { System.out.println("我有一头小毛驴!"); } }
  • 比如要求隔50分钟执行一次,则cron="0 */50 * * * ?",但实际上这种cron表达式的配置到整点都会执行。也就是实际的执行情况如下: 18:50、19:00、19:50、20:00、20:50、21:00 显然这不是我们想要的结果。...
  •  隔1分钟执行一次:0 */1 * * * ?  每天23点执行一次:0 0 23 * * ?  每天凌晨1点执行一次:0 0 1 * * ?  月1号凌晨1点执行一次:0 0 1 1 * ?  月最后一天23点执行一次:0 0 23 L * ?  ...
  • java定时器执行程序

    千次阅读 2019-05-10 16:19:45
    业务场景:需要实时刷新的操作。...//定时刷新频率 5分钟 private static final long PERIOD_DAY = 5 * 60 * 1000; final Timer t = new Timer(); //线程定时执行刷新 t.schedule(new TimerTask() { @Override ...
  • java.swing.Timer定时器的机制似乎是启动之时并不执行任务,必须等到设定的时间间隔到了才执行任务。 即,如果我设定时间间隔是5s.假设计时器启动之时记为时间0,则执行任务的时刻是 * 5s * 10s * 15s * 20s ...
  • java定时器的使用

    2013-02-26 14:37:37
    在应用开发中,经常需要一些周期性的操作,比如5分钟执行操作等。 对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。
  • 手动实现Java定时器

    2021-09-06 12:14:48
    篇我们学到了了阻塞队列,这篇我们将使用阻塞队列和以前提到的优先队列结合体阻塞优先队列来实现个常用的定时器案例。 1. 什么是定时器? ​ 定时器可以强制终止请求:浏览器内部都有定时器,发送了请求...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,230
精华内容 3,692
关键字:

java定时器每分钟执行一次

java 订阅