定时方案更换为ScheduledExecutorService

参考资料

定时方案一直使用Timer,因为调用的不频繁,对时间把控也没有那么绝对的严格,所以也没发现问题。
说一下需求:
以10s为一个周期,每隔1s钟检查一下服务器是否回复,10s钟时仍没有回复,则进入额外20s的超时判断,第30s上仍没回复则提示超时。
使用Timer时,以10s为单位启停一次,实际上是0延迟1秒为周期,用全局变量做计数器去统计10s,结果整个周期最大的时候竟然出现了2s的误差,这是不能接受的。
于是考虑使用JDK5的多线程包ScheduledExecutorService
网上的资料多,而且跟官网范例区别不大,基本只演示了怎么启动任务,怎么停止所有任务,可是我要控制单个任务的停止,资料就很少。
参考了上面那个帖子之后,使用idea做了测试

static int time_1 = 0,time_2=0;
    static Future futureDelay,futureFixedDelay;
    public static void main(String[] args){
        //定时功能测试
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
        System.out.println("before"+System.currentTimeMillis());
//        schedule:延迟多长时间之后只执行一次,执行完自动结束;
        scheduledExecutorService.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("schedule single"+System.currentTimeMillis());
            }
        },0, TimeUnit.MILLISECONDS);

//        scheduledAtFixedRate:延迟指定时间后执行一次,之后按照固定的时长周期执行;
        time_1=0;
        time_2=0;
        futureDelay = scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try{
                    time_1++;
                    System.out.println("schedule delay"+time_1+" mills:"+System.currentTimeMillis());
                    if(time_1>=10){
                        futureDelay.cancel(false);
                        System.out.println("schedule delay finished "+System.currentTimeMillis());
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("schedule Exception:"+e.getMessage());
                }
            }
        },0,1000,TimeUnit.MILLISECONDS);
//        scheduledWithFixedDelay:延迟指定时间后执行一次,之后按照:上一次任务执行时长 + 周期的时长 的时间去周期执行;
        futureFixedDelay=scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                try{
                    time_2++;
                    System.out.println("schedule FixedDelay"+time_2+" mills:"+System.currentTimeMillis());
                    if(time_2>=10){
                        futureFixedDelay.cancel(false);
                        System.out.println("schedule FixedDelay finished " +  System.currentTimeMillis()+" size:"+scheduledExecutorService.shutdownNow().size());

                    }
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("schedule Exception:"+e.getMessage());
                }
            }
        },5000,3000,TimeUnit.MILLISECONDS);
  }

我这里只放了测试代码,添加了三个定时任务,分别测试了
Executors.newScheduledThreadPool(1)
在这里插入图片描述
Executors.newScheduledThreadPool(2)
在这里插入图片描述
Executors.newScheduledThreadPool(3)
在这里插入图片描述
Executors.newSingleThreadScheduledExecutor()
在这里插入图片描述
以上四种情况感觉区别不是很大,误差在5毫秒以内,我最后使用Executors.newSingleThreadScheduledExecutor()感觉就可以了

实际上ScheduledExecutorService 有五个函数可以构建对象,实际上最常用的是newScheduledThreadPool(N)和newSingleThreadScheduledExecutor()
1)newSingleThreadScheduledExecutor
:new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1))
2)newSingleThreadScheduledExecutor(ThreadFactory threadFactory)
:new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1, threadFactory));
3)newScheduledThreadPool(int corePoolSize)
:new ScheduledThreadPoolExecutor(corePoolSize);
4)newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)
:new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
5)unconfigurableScheduledExecutorService(ScheduledExecutorService executor)
:new DelegatedScheduledExecutorService(executor);

之后测试了重复开线程

 static int time_1 = 0,time_2=0;
    static ArrayList<Future> futures;
    static Future futureDelay,futureFixedDelay;
    static  ScheduledExecutorService scheduledExecutorService;
    public static void main(String[] args){
        futures = new ArrayList<>();
        //定时功能测试
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        System.out.println("before"+System.currentTimeMillis());
//        scheduledAtFixedRate:延迟指定时间后执行一次,之后按照固定的时长周期执行;
        time_1=0;
        time_2=1;
        futures.add(scheduledExecutorService.scheduleAtFixedRate(getTask("task"+time_2),0,1000,TimeUnit.MILLISECONDS));
//        futureDelay = ;

    }
    private static Runnable getTask(String taskName){
        return new Runnable() {
            @Override
            public void run() {
                try{
                    time_1++;
                    System.out.println(taskName+" schedule delay"+time_1+" mills:"+System.currentTimeMillis());
                    if(time_1>=10){
                        time_2++;
                        //如果设置true,则表示可以取消正在执行过程中的任务
                        futures.get(futures.size()-1).cancel(true);
                        System.out.println(taskName+"  finished "+System.currentTimeMillis());
                        if(time_2<=5) {
                            time_1=0;
                            futures.add(scheduledExecutorService.scheduleAtFixedRate(getTask("task"+time_2),0,1000,TimeUnit.MILLISECONDS));
//                            futureDelay = scheduledExecutorService.scheduleAtFixedRate(getTask("task" + time_2), 0, 1000, TimeUnit.MILLISECONDS);
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println(taskName+" schedule Exception:"+e.getMessage());
                }
            }
        };
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值