@Scheduled+BlockingQueue实现异步接口

来源:互联网 发布:网络维护外包费用 编辑:程序博客网 时间:2024/06/03 18:20

        之前做的一个同步接口最近需要改成异步接口,开始还以为是消息改成消息队列推送,后来发现其实就是将请求的数据封装放到队列中。然后采用定时器定时的去执行数据。

涉及知识:

        spring的定时器任务:

     fixedDelay  // 在上一个任务完成之后,多久后再次执行:

     fixedRate = 2000//定义一个按一定频率执行的定时任务,每隔多少毫秒执行一     initialDelay = 5000//启动项目后多久开始执行该计划

     cron = "0 0 5 * * *" //格式: [秒] [分] [小时] [日] [月] [周] [年]

    "0 0 12 * * ?"    每天中午十二点触发     "0 15 10 ? * *"    每天早上1015触发     "0 15 10 * * ?"    每天早上1015触发     "0 15 10 * * ? *"    每天早上1015触发     "0 15 10 * * ? 2005"    2005年的每天早上1015触发     "0 * 14 * * ?"    每天从下午2点开始到259分每分钟一次触发     "0 0/5 14 * * ?"    每天从下午2点开始到255分结束每5分钟一次触发     "0 0/5 14,18 * * ?"    每天的下午2点至2556点至655分两个时间段内每5分钟一次触发     "0 0-5 14 * * ?"    每天14:0014:05每分钟一次触发     "0 10,44 14 ? 3 WED"    三月的每周三的14101444触发     "0 15 10 ? * MON-FRI"    每个周一、周二、周三、周四、周五的1015触发 

        BlockingQueue:线程阻塞队列。是一个 高效并且线程安全的队列类

         add(E o); //将指定的元素添加到此队列中(如果立即可行),在成功时返回 true,其他情况则抛出 IllegalStateException。  
        drainTo(Collection<? super E> c);  //移除此队列中所有可用的元素,并将它们添加到给定 collection 中。  
        drainTo(Collection<? super E> c,int maxElements);//最多从此队列中移除给定数量的可用元素,并将这些元素添加到给定 collection 中  
        offer(E o);  //如果可能的话,将指定元素插入此队列中。  
        offer(E o, long timeout, TimeUnit unit);  //将指定的元素插入此队列中,如果没有可用空间,将等待指定的等待时间(如果有必要)。  
        poll(long timeout, TimeUnit unit);  //检索并移除此队列的头部,如果此队列中没有任何元素,则等待指定等待的时间(如果有必要)。  
        put(E o);    //将指定元素添加到此队列中,如果没有可用空间,将一直等待(如果有必要)。  
        remainingCapacity();  //返回在无阻塞的理想情况下(不存在内存或资源约束)此队列能接受的元素数量;如果没有内部限制,则返回 Integer.MAX_VALUE。  
        take();  //检索并移除此队列的头部,如果此队列不存在任何元素,则一直等待。 


实现过程:

      1.  首先写一个普通的类,并加标签@Component,让spring可以扫描到

      2. 定义一个public static BlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(1000);的队列。并初始化大小,我这里设为1000

      3. 写一个普通的方法。加上spring定时器的注解@Scheduled,设置具体的执行计划。方法中写具体的处理方法

      4.在提供出去的接口处添加具体的代码。每次别人访问的时候将请求数据封装成对象添加到队列中。注意:这里要判断队列是否满了。


具体demo:

        1. TestTaskService

@Component
public class TestTaskService {

    private static Logger log = Logger.getLogger(TestTaskService.class);
    
    public static BlockingQueue<User> queue = new LinkedBlockingQueue<User>(1000);
    
    @Autowired
    public TestTaskMapper testTaskMapper;

     @Scheduled(fixedRate = 2000, initialDelay = 5000)
        public void dealCoupon() {
            try {
                List<User> list = new ArrayList<User>();
                queue.drainTo(list, 50);
                if(list.size()>0){
                    log.info("测试定时器开始。。。。:" + list.size());
                    for(User o:list){
                        int age = o.getAge();
                        String name = o.getName();
                        try {
                            testTaskMapper.addUser(name, age);
                        } catch (Exception e) {
                             log.info("添加失败"+e);
                        }
                    }
                }
            } catch (Exception e) {
                log.error("添加失败" + e, e);
            }
        }  
}

        2. TestTaskController

@RequestMapping("/")
@Controller
public class TestTaskController {
@RequestMapping("/task")
@ResponseBody
    public String testTask(String name,String password){
        try {
            appendCoupons(name, Integer.valueOf(password));
        } catch (Exception e) {
            return "添加失败";
        }
        return "测试定时任务";
    }
    private void appendCoupons(String name, int age) throws Exception {
        User u=new User();
        u.setName(name);
        u.setAge(age);
        if(TestTaskService.queue.size()>999) {
            throw new java.lang.Exception("添加失败");
        }else{
            TestTaskService.queue.add(u);
        }
    }
    
}

        3. TestTaskMapper

public interface TestTaskMapper {

    public void addUser(@Param("name")String name, @Param("age")int age);

}


4.TestTaskMapper.xml

<?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.cjx.firstSpringboot.mapper.TestTaskMapper">
 
    <insert id="addUser">
    
        insert into user value (null,#{name},#{age})
    
    </insert>

</mapper>









原创粉丝点击