需要帮助。一旦我设置了Timer.schedule,Run方法就会被调用两次。 你可以帮忙吗? 我正在使用jdk1.7和Timer和TimerTask类。
我的代码
的web.xml
<listener>
<listener-class>com.globeop.gobookmanager.startup.ScheduleReportManager</listener-class>
</listener>
public class ScheduleReportManager implements ServletContextListener{
private ServletContext application = null;
private Environment environment =null;
private Timer scheduledReportTimer=null;
private ConcurrentHashMap scheduledReportTimerTasks;
ApplicationContext webContext=null;
public ScheduleReportManager() {
}
public void contextInitialized(ServletContextEvent servletContextEvent) {
try{
this.application= servletContextEvent.getServletContext();
webContext = (ApplicationContext) application.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if(application.getAttribute("scheduledReportTimer")==null)
{
application.setAttribute("scheduleReportManager",this);
this.scheduledReportTimer= new Timer(true);
setupSchedule(scheduledReportTimer, application);
application.setAttribute("scheduledReportTimer", scheduledReportTimer);
}
Logger.global.log(Level.INFO, "ScheduledReportTimer: " + application.getServletContextName() + ": Setup completed");
} catch (Exception e)
{
Logger.global.log(Level.SEVERE, "Setup Report Timer Exception - " + e.toString());
}
}
public void setupSchedule(Timer scheduledReportTimer, ServletContext application) throws Exception{
this.environment = SpringBridgeUtil.retrieveEnvironment(application);
this.scheduledReportTimerTasks= new ConcurrentHashMap();
ScheduledReportTimerTask scheduledReportTimerTask = new ScheduledReportTimerTask(application,environment,this);
scheduledReportTimerTasks.put(environment.getCode(),scheduledReportTimerTask);
scheduledReportTimer.schedule(scheduledReportTimerTask,1000);
}
public void setTimerForNextExecution(ScheduledReportTimerTask timerTask, DateTime nextExecutionDateTime)
{
if(nextExecutionDateTime == null)
return;
Environment environment = timerTask.getEnvironment();
ServletContext application = timerTask.getApplication();
ScheduledReportTimerTask scheduledReportTimerTask = new ScheduledReportTimerTask(application,environment,this);
java.util.Date nextScheduleTime = nextExecutionDateTime.getDate();
String environmentCode = environment.getCode();
synchronized (scheduledReportTimerTasks){
scheduledReportTimerTasks.put(environmentCode,scheduledReportTimerTask);
Logger.global.log(Level.INFO, "ScheduledReportManager: next execution time is " + nextScheduleTime.toString());
scheduledReportTimer.schedule(scheduledReportTimerTask,nextScheduleTime);
}
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
String contextName = application.getServletContextName();
if (scheduledReportTimer != null) {
scheduledReportTimer.cancel();
}
Logger.global.log(Level.INFO, "scheduledReportTimer: " + contextName
+ ": Tasks cancelled due to context removal");
}
}
我的理解是一次scheduleReportTimer.schedule(scheduledReportTimerTask,1000);执行它调用类scheduledReportTimerTask的run()。是的,是的。但是我从记录器中发现运行方法被调用了两次。
public class ScheduledReportTimerTask extends TimerTask{
private ServletContext application;
private Environment environment;
private ScheduleReportManager scheduledReportManager;
private EmailNotificationDao emailNotificationDao;
private DataSource dataSource;
private ClientDao clientDao;
private EmployeeDao employeeDao = null;
public ServletContext getApplication() {
return application;
}
public Environment getEnvironment() {
return environment;
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
public void setApplication(ServletContext application) {
this.application = application;
}
public ScheduledReportTimerTask(ServletContext application, Environment environment, ScheduleReportManager scheduledReportManager) {
this.application = application;
this.environment = environment;
this.scheduledReportManager = scheduledReportManager;
ApplicationContext webContext=(ApplicationContext) application.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
this.emailNotificationDao = (EmailNotificationDao) webContext.getBean("emailNotificationDao");
this.clientDao = (ClientDao) webContext.getBean("clientDao");
this.dataSource= (DataSource) webContext.getBean("gofundsDataSource");
this.employeeDao = (EmployeeDao) webContext.getBean("employeeDao");
}
public ScheduledReportTimerTask() {
}
public void run()
{
try{
synchronized (this){
Logger.global.log(Level.INFO,"schedule ReportTimerTask is running " + new DateTime());
List <ClientEmailNotification>scheduleReports = this.getScheduleReportList();
if(scheduleReports!=null && scheduleReports.size()>0)
{
processReports(scheduleReports);
}
DateTime nextExecutionTime = this.getNextExecutionTime();
scheduledReportManager.setTimerForNextExecution(this,nextExecutionTime);
Logger.global.log(Level.INFO, "ScheduleReportTimerTask task completed"+ new DateTime());
}
}catch (Exception e) {
e.printStackTrace();
Logger.global.log(Level.INFO,"ScheduledReportTimerTask exception " + e.toString());
DateTime dateTime = new DateTime();
dateTime.adjustMinute(10);
scheduledReportManager.setTimerForNextExecution(this,dateTime);
}
}
}
请帮助!!!
我正在使用java.util.logging;用于记录的包 请看我的评论
synchronized (this){
Logger.global.log(Level.INFO,"schedule ReportTimerTask is running " + new DateTime()); // this print twice
List <ClientEmailNotification>scheduleReports = this.getScheduleReportList();
if(scheduleReports!=null && scheduleReports.size()>0)
{
processReports(scheduleReports);
}
DateTime nextExecutionTime = this.getNextExecutionTime();
scheduledReportManager.setTimerForNextExecution(this,nextExecutionTime);
Logger.global.log(Level.INFO, "ScheduleReportTimerTask task completed"+ new DateTime()); // this print twice
}
查看我的tomcat日志
21-Jul-2014 11:00:00.001:INFO:schedule ReportTimerTask正在运行21-Jul-2014 11:00:00
21-Jul-2014 11:00:00.002:INFO:schedule ReportTimerTask正在运行21-Jul-2014 11:00:00
21-Jul-2014 11:00:14.332:INFO:ScheduleReportTimerTask任务已完成21-Jul-2014 11:00:14
21-Jul-2014 11:00:14.446:INFO:ScheduleReportTimerTask任务已完成21-Jul-2014 11:00:14
好的..我在server.xml中找到了以下配置
<Server port="8135" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources -->
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8139" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
<Engine name="Catalina" defaultHost="gofunds.globeop.com" jvmRoute="ajp_gobookmanager">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
<Host name="gofunds.globeop.com"
appBase="webapps"
unpackWARs="true"
autoDeploy="true"
xmlValidation="false"
xmlNamespaceAware="false">
<Context path="" docBase="../webapps/gobookmanager" debug="0" />
<Context path="/manager" debug="0" privileged="true"
docBase="/home/gofunds/tomcat/webapps/manager">
<ResourceLink name="users"
global="UserDatabase"
type="org.apache.catalina.UserDatabase" />
</Context>
</Host>
</Engine>
</Service>
</Server>
配置是否正确?