package com.cmbc.web.exam.dynamic;
import com.cmbc.web.exam.testOnline.model.TestPaper;
import com.cmbc.web.exam.testOnline.service.TestOnlineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Hashtable;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;
@Component
public class DynamicTaskService {
private Hashtable<String, TestPaper> paperMap = new Hashtable();
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Autowired
private TestOnlineService testOnlineService;
private ScheduledFuture<?> future;
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
return new ThreadPoolTaskScheduler();
}
public void addPaper(TestPaper testPaper) {
if (future == null) {
//开启定时任务
startCron();
}
System.out.println("添加交卷" + new Date().toLocaleString());
paperMap.put(testPaper.getId(), testPaper);
}
private String startCron() {
future = threadPoolTaskScheduler.schedule(new MyRunnable(), new CronTrigger("0/5 * * * * ? "));
System.out.println("启动--定时轮询交卷任务");
return "startCron";
}
public String stopCron() {
if (future != null) {
future.cancel(true);
future = null;
paperMap.clear();
}
System.out.println("停止--定时轮询交卷任务");
return "stopCron";
}
private class MyRunnable implements Runnable {
@Override
public void run() {
long timeCurrent = new Date().getTime();
Set keys = paperMap.keySet();
for (Object key : keys) {
TestPaper paper = paperMap.get(key);
if (paper == null) {
paperMap.remove(key);
continue;
}
//计算结束时间(在原来基础上加5秒钟)
//long sotpTime = paper.getBeginTime().getTime() + paper.getTime() * 60 * 1000l + 5000;
long sotpTime = paper.getBeginTime().getTime() + 10000;
if (sotpTime <= timeCurrent) {
//时间结束调用交卷方法
try {
testOnlineService.handInPaper(paper);
System.out.println("执行交卷" + new Date().toLocaleString());
} catch (Exception e) {
e.printStackTrace();
}
//移除数据
paperMap.remove(key);
}
}
if (paperMap.size() == 0) {
//停止轮询
stopCron();
}
}
}
}
该方式采用轮询方式,开启定时任务,扫描是否需要提交的试卷,也想采用每一张试卷开始考试创建一个定时任务,但是我测试时候发现,定时任务执行的时间不准确,一般快于正常的倒计时时间,所有采用轮询, 提交时候虽然有一定的误差,不过对于目前页面影响不打
本实例修改与 博客: