ScheduledExecutorService异常分析
2018-03-21 本文已影响0人
田园小丁
一、源码解析
关注一块代码:
/**
* Creates and executes a periodic action that becomes enabled first
* after the given initial delay, and subsequently with the given
* period; that is executions will commence after
* {@code initialDelay} then {@code initialDelay+period}, then
* {@code initialDelay + 2 * period}, and so on.
* If any execution of the task
* encounters an exception, subsequent executions are suppressed.
* Otherwise, the task will only terminate via cancellation or
* termination of the executor. If any execution of this task
* takes longer than its period, then subsequent executions
* may start late, but will not concurrently execute.
*
* @param command the task to execute
* @param initialDelay the time to delay first execution
* @param period the period between successive executions
* @param unit the time unit of the initialDelay and period parameters
* @return a ScheduledFuture representing pending completion of
* the task, and whose {@code get()} method will throw an
* exception upon cancellation
* @throws RejectedExecutionException if the task cannot be
* scheduled for execution
* @throws NullPointerException if command is null
* @throws IllegalArgumentException if period less than or equal to zero
*/
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
二、说明
由scheduleAtFixedRate产生的周期工作线程,如果遇到任何意外则会停止后续执行;
如果执行的Runnable线程任务没有加异常,则会出现只执行一次则线程停止的问题!特别引起重视!
三、总结
1、获取一个线程池定时任务异常关闭的小tip,注意任何心跳类希望一直保持线程定时任务,为保证线程可靠性,最好捕获异常进行相关保护;
2、灵感源于代码,因此切忌遇到问题要关注代码底层实现,学会看jdk文档接口的详细说明,可以少走很多弯路;
3、学习ScheduledFuture这个返回:
- 继承了Delayed, Future<V>两个接口
- long getDelay(TimeUnit unit);支持返回线程任务的最近间隔时间
- future提供的cancel、get等方法用于任务取消或者获取,作用也很重要,注意学习用法
四、测试代码
package FutureScheuledTest;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* Created by fwding on 2018/3/21 0021.
*/
public class FutureScheduledTest {
private static ScheduledFuture global_sfd;
public static void main(String[] args) throws Exception {
ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);
ScheduledFuture sfa = ses.scheduleAtFixedRate(new TimerTask("a"), 200,
1000, TimeUnit.MILLISECONDS);
ScheduledFuture sfb = ses.scheduleAtFixedRate(new TimerTask("b"), 400,
1000, TimeUnit.MILLISECONDS);
ScheduledFuture sfc = ses.scheduleAtFixedRate(new TimerTask("c"), 600,
1000, TimeUnit.MILLISECONDS);
global_sfd = ses.scheduleAtFixedRate(new TimerTask("d"), 800,
1000, TimeUnit.MILLISECONDS);
Thread.sleep(5000);
sfa.cancel(true);
sfb.cancel(true);
sfc.cancel(true);
global_sfd.cancel(true);
Thread.sleep(5000);
ses.shutdown();
}
static class TimerTask implements Runnable{
private String id;
public TimerTask(String id){
this.id = id;
}
@Override
public void run(){
System.out.println(id);
//
System.out.println("ID:" + id +"------------THREAD_D:TIME DELAY:" +
global_sfd.getDelay(TimeUnit.MILLISECONDS));
if (!id.equals("d") && global_sfd.getDelay(TimeUnit.MILLISECONDS) < 400) {
global_sfd.cancel(true);
System.out.println("ID:" + id +"------------stop the THREAD_D!!!!!!");
Thread.currentThread().stop();
}
//异常测试
/*
try {
int[] s = new int[2];
s[0] = 1;
s[1] = 2;
s[2] = 3;
} catch (Exception e) {
e.printStackTrace();
}
*/
}
}
}