ScheduledThreadPoolExecutor称作多线程调度器,继承自ThreadPoolExecutor,添加了按计划执行线程操作的功能,如:延迟,定时,周期执行任务。
一、它继承自ThreadPoolExecutor,首先来看看它的家族。
二、调度方法
(1)schedule(Runnable , delay, TimeUnit):延迟执行任务
(2)scheduleAtFixedRate(Runnable , delay, period, TimeUnit):定期执行任务,若执行任务时间超过指定周期时间period,则执行完毕后会立即执行下次任务。
(3)scheduleWithFixedDelay(Runnable , delay, period , TimeUnit):也是定期执行任务,差别在于该方法period是指每次执行完毕后,间隔period时间,在执行下次任务。
三、与Timer比较
Timer的缺点:
(1)Timer内部只创建了一个线程,如果某个任务耗时,就会影响其他的任务执行。
(2)Timer没有处理异常,在跑多个任务时,只要其中之一没有捕获异常,其他的任务也会终止。
故jdk1.5后推荐使用ScheduledThreadPoolExecutor来代替Timer。
四、ThreadPoolExecutor的使用
final ScheduledThreadPoolExecutor poolExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
@Override
public Thread newThread(@NonNull Runnable runnable) {
Thread thread = new Thread(runnable);
//设置为守护线程
thread.setDaemon(true);
thread.setName("Thread--001");
return thread;
}
});
final long startTime = System.currentTimeMillis();
poolExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
long endTime = System.currentTimeMillis();
final long time = (endTime - startTime) / 1000;
Log.i(initTag(), "time:" + time);
if (time >= 5) {
poolExecutor.shutdown();
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
thread_tv1.setText(time + "");
}
});
}
}
}, 0, 1, TimeUnit.SECONDS);
五、守护线程与用户线程
thread.setDaemon(true)即为将该线程设置为守护线程;相反设置为true即为用户线程,默认为用户线程。
区别:守护线程也称服务线程,优先级比较低。如果程序中用户线程有结束了,程序也会退出,不管守护线程是否结束,但只要有一个user线程,程序就不会退出。垃圾回收线程就是一个守护线程,如果程序中没有了运行的thread,那么改程序也就没有垃圾可供回收,回收线程就会自动离开。
主意一点:setDaemon(boolean)方法一定要在thread.start()之前,否则线程启动后设置无效。