zoukankan      html  css  js  c++  java
  • 关于超时的实现---利用Timer

    对于一些业务逻辑。需要用到超时处理的,在规定时间内没有得到回复,那么就需要处理。

    比如:转账服务,

    1)A转100给B。

    2)B收到100后,回复A说,已经收到了。(这里就有时间限制)

    3)A收到B的回复

    对于操作1)是否有效需要操作3)来确定。操作1)是一个单独的请求。这个请求完了就完了。

     核心是Timer的使用。验证超时就需要一个定时器。设置执行间隔,执行次数。

    超时处理需要一个hander

    public abstract class TimeoutHandler {
        /** 执行周期(毫秒) */
        private int period = 1000 * 60 * 3;
        /** 延迟时间(毫秒) */
        private int delay = 1000 * 60 * 3;
        /** 执行次数(>=1) */
        private int times = 1;
        /** 定时器 */
        private Timer timer;
    
        /**
         * 超时处理
         * 
         * @param _period
         *            执行周期(秒)
         * @param _times
         *            执行次数(>=1)
         */
        public TimeoutHandler(int _period, int _times) {
            super();
            this.period = 1000 * _period;
            this.delay = this.period;
            this.times = _times;
    
            timer = new Timer();
            if (times > 1) {// 执行多次
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        if (times > 1) {
                            times--;
    
                            retry();
                        } else {
                            end();
    
                            timer.cancel();// 结束任务
                        }
                    }
                }, delay, period);
            } else {// 执行一次
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        end();
    
                        timer.cancel();// 结束任务
                    }
                }, delay);
            }
        }
    
        /**
         * 终止任务
         */
        public void cancel() {
            if (timer != null) {
                timer.cancel();
            }
        }
    
        /**
         * 重试
         */
        public abstract void retry();
    
        /**
         * 终结
         */
        public abstract void end();
    
    }
    TimeOut

    超时类的实际处理

    public class Up0x26 extends TimeoutHandler {
        private static Logger logger = LoggerFactory.getLogger(Up0x26.class);
        /** 执行周期(秒) */
        private static final int period = 60 * 3;
        /** 执行次数(>=1) */
        private static final int times = 1;
        /** A */
        private String A;
        
        
        /**
         * 0x78超时处理
         * 
         * @param params
         *            参数
         */
        public Up0x26(String A ) {
            super(period, times);
    
            
            this.A=A;
        }
    
        @Override
        public void retry() {
            logger.info("未及时收到回复 A:" + A );
        }
    
        @Override
        public void end() {
            logger.info("[超时]未及时A:停止失败.A" + A );
        }

    针对多个超时需要一个管理器管理起来。

    public class TimeoutManager {
        private static Logger logger = LoggerFactory.getLogger(TimeoutManager.class);
        /** 单例 */
        private static volatile TimeoutManager singleton = null;
        
        
        /** 缓存 -0x26 */
        private Map<String, List<TimeoutHandler>> Cache0x26 = null;
        
        
        /** 集合 - 超时处理类 */
        @SuppressWarnings("rawtypes")
        private static Class[] handlerSet = { Up0x26.class };
    
        /** 私有构造方法 */
        private TimeoutManager() {
            super();
    
            
            Cache0x26 = new ConcurrentHashMap<String, List<TimeoutHandler>>();
        }
    
        /** 获取实例 */
        public static TimeoutManager getInstance() {
            if (singleton == null) {
                synchronized (TimeoutManager.class) {
                    if (singleton == null) {
                        singleton = new TimeoutManager();
                    }
                }
            }
            return singleton;
        }
    
        /**
         * 获取缓存
         * 
         * @param c
         *            超时处理对象类型
         * @return null 或 缓存对象
         */
        private Map<String, List<TimeoutHandler>> getCache(Class<? extends TimeoutHandler> c) {
             
             if (c == Up0x26.class) {
                return Cache0x26;
            } else {
                return null;
            }
        }
    
        /**
         * 添加超时监控
         * 
         * @param key
         *            标识
         * @param handler
         *            超时处理对象
         */
        public void add(String key, TimeoutHandler handler) {
            if (key == null || "".equals(key = key.trim()) || handler == null) {
                return;
            }
    
            Map<String, List<TimeoutHandler>> cache = getCache(handler.getClass());
            if (cache == null) {
                logger.error("[添加超时监控]未知的对象类型:" + handler.getClass());
                return;
            }
    
            logger.info("[添加超时监控]key:" + key + " type:" + handler.getClass().getSimpleName());
            synchronized (cache) {
                List<TimeoutHandler> list = cache.get(key);
                if (list == null) {
                    list = new ArrayList<TimeoutHandler>();
                }
                list.add(handler);
    
                cache.put(key, list);
            }
        }
    
        /**
         * 删除超时监控
         * 
         * @param key
         *            
         * @param c
         *            超时处理对象类型
         */
        public void delete(String key, Class<? extends TimeoutHandler> c) {
            if (key == null || "".equals(key = key.trim()) || c == null) {
                return;
            }
    
            Map<String, List<TimeoutHandler>> cache = getCache(c);
            if (cache == null) {
                logger.error("[删除超时监控]未知的对象类型:" + c);
                return;
            }
    
            logger.info("[删除超时监控]key:" + key + " type:" + c.getSimpleName());
            synchronized (cache) {
                List<TimeoutHandler> list = cache.get(key);
                if (list != null && !list.isEmpty()) {
                    for (TimeoutHandler handler : list) {
                        handler.cancel();
                    }
                }
                cache.remove(key);
            }
        }
    
        /**
         * 删除所有种类的超时监控
         * 
         * @param key
         *            标识
         */
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public void deleteAll(String key) {
            if (key == null || "".equals(key = key.trim())) {
                return;
            }
    
            for (Class c : handlerSet) {
                delete(key, c);
            }
        }
    
        /**
         * 是否存在超时监控
         * 
         * @param key
         *            标识
         * @param c
         *            超时处理对象类型
         * @return true:存在 false:不存在
         */
        public boolean containsKey(String key, Class<? extends TimeoutHandler> c) {
            if (key == null || "".equals(key = key.trim()) || c == null) {
                return false;
            }
    
            Map<String, List<TimeoutHandler>> cache = getCache(c);
            if (cache == null) {
                logger.error("[是否存在超时监控]未知的对象类型:" + c);
                return false;
            }
    
            return cache.containsKey(key);
        }
    
    }
    timeOutManager

    超时的使用:

    添加超时监控:

    TimeoutManager.getInstance().add(key, new Up0x26(A));// 添加超时监控

    删除超时监控:

    TimeoutManager.getInstance().delete(key, Up0x26.class);// 删除超时监控
    学习的时间不一定要特定安排
  • 相关阅读:
    ecshop 浏览历史样式的修改
    ECSHOP任意页面调用商品属性
    ECShop url路径 商品详情页goods 商品列表页category 修改成你想要的
    ecshop模板增加新lbi库文件注意事项
    最完美带qq昵称qq头像的qq帐号登录ecshop插件
    ECSHOP2.72 前台调用 定单号,及收货人,快递号
    ecshop后台帐号密码忘记了怎么办?
    ECSHOP首页成功实现订单上下滚动
    ECSHOP 注册就送红包
    ECSHOP隐藏帮助中心文章页的评论功能方法
  • 原文地址:https://www.cnblogs.com/zhongzheng123/p/7531208.html
Copyright © 2011-2022 走看看