必威体育Betway必威体育官网
当前位置:首页 > IT技术

定时任务ScheduledThreadPoolExecutor的使用详解

时间:2019-10-29 12:43:36来源:IT技术作者:seo实验室小编阅读:88次「手机版」
 

scheduledthreadpoolexecutor

定时任务scheduledthreadpoolexecutor的使用详解

前短时间需要用到一个定时器处理蓝牙设备接收的数据,并且需要处理的频率是很快的,这就需要一个稳定的定时器来保证数据的长久进行。ScheduledThreadPoolExecutor这个类就是个很好的选择。

正常情况下,定时器我们都是用Timer和TimerTask这两个类就能完成定时任务,并且设置延长时间和循环时间间隔。

ScheduledThreadPoolExecutor也能完成Timer一样的定时任务,并且时间间隔更加准确。

误差说明:

我在后台程序看看一下Timer执行程序是有可能延迟1、2毫秒,如果是1秒执行一次的任务,1分钟有可能延迟60毫秒,一小时延迟3600毫秒,相当于3秒,实际用户看不出什么区别。

但是,如果我的程序需要每40毫秒就执行一次任务,如果还是有1、2毫秒的误差,1秒钟就有25毫秒的误差,大概40秒就有1秒的误差,十几分钟就有十几秒的误差,这对UI显示来说是延迟非常严重的了。

而我用ScheduledThreadPoolExecutor来做40毫秒的间隔任务,一般十几分钟才有1秒多的误差,这个还是能接受的。

这也是我用ScheduledThreadPoolExecutor这个类的原因。

ScheduledThreadPoolExecutor的介绍

ScheduledThreadPoolExecutor,它可另行安排在给定的延迟后运行命令,或者定期执行命令。需要多个辅助线程时,或者要求 ThreadPoolExecutor 具有额外的灵活性或功能时,此类要优于Timer。

使用Timer和TimerTask存在一些缺陷:

1.Timer只创建了一个线程。当你的任务执行的时间超过设置的延时时间将会产生一些问题。

2.Timer创建的线程没有处理异常,因此一旦抛出非受检异常,该线程会立即终止。

JDK 5.0以后推荐使用ScheduledThreadPoolExecutor。该类属于Executor Framework,它除了能处理异常外,还可以创建多个线程解决上面的问题

Timer和TimerTask的使用

这个大家应该都是会使用的了,但是还是給给大家看看代码

        Timer  timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                log.e("time:");

            }
        }, 2000, 40);//2000表示第一次执行任务延迟时间,40表示以后每隔多长时间执行一次run里面的任务
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ScheduledThreadPoolExecutor的使用

这里先学会简单使用再深入探讨。

        ScheduledThreadPoolExecutor  scheduled = new ScheduledThreadPoolExecutor(2);
        scheduled.scheduleatfixedrate(new Runnable() {
            @Override
            public void run() {
                loge("time:");
            }
        }, 0, 40, TimeUnit.MILLISECONDS);//0表示首次执行任务的延迟时间,40表示每次执行任务的间隔时间,TimeUnit.MILLISECONDS执行的时间间隔数值单位

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

间隔单位毫秒:TimeUnit.MILLISECONDS

间隔单位秒:TimeUnit.SECONDS

间隔单位分钟:TimeUnit.MINUTES

间隔单位小时:TimeUnit.HOURS

间隔单位天:TimeUnit.DAYS

定时器的一个实例

使用Timer和TimerTask、ScheduledThreadPoolExecutor显示秒的定时器

效果:

1

这里看起来是每秒刷新一次UI,但是我为了看40毫秒的延迟效果,是每40 毫秒index加一,添加25次后,刷新一次UI,表面上看起来是和每秒刷新的效果。

代码:

package com.example.wenzhi.scheduledthreadpoolexecutordemo;

import Android.os.handler;
import android.os.message;
import android.support.v7.APP.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    TextView tv_time;
    int      time;

    @Override
    protected void onCreate(Bundle savedinstanceState) {
        super.onCreate(savedInstanceState);
        setcontentView(R.layout.activity_main);
        tv_time = (TextView) findViewById(R.id.tv_time);

    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (time % 25 == 0) {
                tv_time.setText("" + time / 25);
            }
        }
    };

    /**
     * 普通定时器
     */
    Timer timer;

    public void timer(View view) {
        stopTimer1();
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                loge("time:" + time++);//add
                handler.sendemptyMessage(11);
            }
        }, 2000, 40);
    }

    public void stop(View view) {
        stopTimer1();
    }

    /**
     * 停止定时器
     */
    private void stopTimer1() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }


    /**
     * 稳定的定时器
     */
    ScheduledThreadPoolExecutor scheduled;

    public void timer2(View view) {
        stopTimer2();
        scheduled = new ScheduledThreadPoolExecutor(2);
        scheduled.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                loge("time:" + time++);
                handler.sendEmptyMessage(11);
            }
        }, 0, 40, TimeUnit.MILLISECONDS);

    }

    public void stop2(View view) {
        stopTimer2();
    }

    /**
     * 停止定时器
     */
    private void stopTimer2() {
        if (scheduled != null) {
            scheduled.shutdownNow();
            scheduled = null;
        }
    }

    private void loge(String msg) {
        Log.e("TAG", msg);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        System.exit(0);
    }

    /**
     * 数据清零
     */
    public void clear(View view) {
        time = 0;
        tv_time.setText("" + time);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122

Log数据对比

Timer定时器

11-29 01:08:09.940 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:0
11-29 01:08:09.980 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:1
11-29 01:08:10.020 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:2
11-29 01:08:10.060 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:3
11-29 01:08:10.100 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:4
11-29 01:08:10.140 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:5
11-29 01:08:10.180 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:6
11-29 01:08:10.224 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:7
11-29 01:08:10.264 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:8
11-29 01:08:10.304 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:9
11-29 01:08:10.344 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:10
11-29 01:08:10.384 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:11
11-29 01:08:10.424 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:12
11-29 01:08:10.468 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:13
11-29 01:08:10.508 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:14
11-29 01:08:10.548 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:15
11-29 01:08:10.592 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:16
11-29 01:08:10.632 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:17
11-29 01:08:10.672 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:18
11-29 01:08:10.712 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:19
11-29 01:08:10.752 6070-20203/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

可以看到上面时间间隔不是很稳定,有几个是间隔40多毫秒的

ScheduledThreadPoolExecutor定时器

11-29 01:11:13.492 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:0
11-29 01:11:13.528 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:1
11-29 01:11:13.564 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:2
11-29 01:11:13.604 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:3
11-29 01:11:13.644 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:4
11-29 01:11:13.684 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:5
11-29 01:11:13.724 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:6
11-29 01:11:13.764 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:7
11-29 01:11:13.804 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:8
11-29 01:11:13.844 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:9
11-29 01:11:13.888 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:10
11-29 01:11:13.924 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:11
11-29 01:11:13.984 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:12
11-29 01:11:14.004 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:13
11-29 01:11:14.044 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:14
11-29 01:11:14.084 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:15
11-29 01:11:14.124 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:16
11-29 01:11:14.164 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:17
11-29 01:11:14.204 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:18
11-29 01:11:14.244 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:19
11-29 01:11:14.284 6070-22987/com.example.wenzhi.scheduledthreadpoolexecutordemo E/TAG: time:20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

可以看到上面的数据除了第一个和第二个,其他的数据都是非常稳定的,间隔时间都是40毫秒。

而且时间越长越能看出,这两种定时器的差距。

不忘初心

文章最后发布于: 2018-08-31 15:33:24

相关阅读

如何让营销QQ每天1000次邀请不受限制加好友?

营销QQ是拥有10万好友容量的一个企业版QQ,可以每天发出1000次好友邀请,但是很多用户在购买使用之后,发现并不能达到1000次邀请量,经常

浅谈setInterval(aa,1000)与setInterval(aa(),1000)的

一直有个疑惑,在定时器上调用某个方法时,加括号和不加括号有什么区别。今天做了个实验,发现,不加括号定时器会每秒执行一次,加了括号只

做3年社群投入1000万,我都明白了什么?

图片来源图虫:已授站长之家使用声明:本文来自于微信公众号运营研究社公众号(ID:U_quan),作者:陈维贤,授权站长之家转载发布。文章整理自

E1000 与 VMXNET3的 区别

与E1000E和E1000相比,VMXNET3的网络性能更好。本文将解释虚拟网络适配器和第2部分之间的区别,并将演示通过选择半虚拟化适配器可以

java中Executor框架之ThreadPoolExcutor和ScheduledTh

转载自: https://blog.csdn.net/javazejian/article/details/50890554 java多线程-概念&创建启动&中断&守护线程&

分享到:

栏目导航

推荐阅读

热门阅读