关于后端:倒计时-任务调度

对于我的项目中,业务层是必不可少的一环,而除了最根本的对于数据库咱们会进行Dao层的jdbc增删改查操作之外,还会依据我的项目需要进行各种业务操作,本文次要说一下一种倒计时的业务,相似于购票时对于歹意订单达到工夫的主动删除.

而实现任务调度的形式也有很多,本文次要说的是Java中自带的Timer来实现.

1.构建Timer对象

//1.1构建timer对象
Timer timer=new Timer();

第一步是构建Timer对象,这个对象的作用是负责去执行一些调度工作(内置了一个线程和一个工作队列).

2.启动线程执行工作

timer.schedule(new TimerTask() {]\
    @Override
    public void run() {
        System.out.println("执行工作...");
        activityDao.updateState(activity.getId());
        timer.cancel();
    }
}, activity.getEndTime());

如下图所示,Timer的api中有多个schedule办法,咱们这里应用的是第一个,须要传入两个参数

其中TimerTask为工作对象,其中有一个须要重写的办法(run()),run()办法内就是工作须要执行的内容,一旦调用此工作的线程取得了CPU,就会去执行run()

另一个是指定的工夫,这里是activity.getEndTime(),获取的流动对象的完结工夫,要达到的目标是,达到设定的流动完结工夫,通过dao层的办法将流动的状态置为0也就是有效化.

执行完工作后能够执行timer.cancel(),退出任务调度,线程也就会销毁,解放内存.

3.引出问题

因为咱们这里的业务是要在新增流动时,开启这个工作的线程,开始进行倒计时,当达到新增时输出的流动完结工夫主动扭转状态(也就是state参数),这就呈现了一个问题–咱们在新增时,个别id都是设为自增的主键,新增时传入的也就是null,那么咱们怎么对数据库进行操作扭转state的值呢?

这时,因为像新增这种较长的sql语句咱们都是在mapper.xml文件中写的–>在<insert>标签中增加–>useGeneratedKeys=”true” keyProperty=”id”

设置了这两个参数,咱们就能够通过getId办法拿到咱们须要的id了,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <mapper namespace="com.cy.pj.activity.dao.ActivityDao">
     <insert id="insertActivity" useGeneratedKeys="true" keyProperty="id" parameterType="com.cy.pj.activity.pojo.Activity">
         insert into tb_activity      (title,category,startTime,endTime,remark,state,createdUser,createdTime) 
         values 
         (#{title},#{category},#{startTime},#{endTime},#{remark},#{state},#{createdUser},now())
     </insert>
  </mapper>

那么,这两个要害的参数到底是什么含意:

useGeneratedKeys=“true” keyProperty=“id”
useGeneratedKeys设置为 true 时,示意如果插入的表id以自增列为主键,则容许JDBC反对主动生成主键,并可将主动生成的主键id返回。
useGeneratedKeys参数只针对insert语句失效,默认为 false;
keyProperty示意将取得自增主键赋值给参数对象的哪个属性.

当然不只是xml文件中能够应用这两个参数,用注解形式写sql语句也同样能够应用:

须要在@insert注解下加上
@Options(useGeneratedKeys = true,keyProperty = “id”)注解即可,含意和xml文件雷同.

4.Timer存在问题

Timer只创立惟一的线程来执行所有timer工作.如果一个timer工作的执行很耗时,会导致其余TimerTask的时效准确性出问题.
Timer的另一个问题在于,如果TimerTask抛出未查看的异样,Timer将会产生无奈意料的行为.Timer线程并不捕捉异样,所以TimerTask抛出的未查看的异样会终止timer线程.这种状况下,Timer也不会再从新复原线程的执行了;它谬误地认为整个Timer被勾销了.

这样来看Timer的问题还很重大,业务少的状况还好说,然而真正工作中,业务必定少不了,所以根本在JDK5.0之后很少有应用Timer了,更多是应用ScheduledExecutor或是第三方框架Quartz.大家能够自行理解一下.

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理