一、源碼解析
關(guān)注一塊代碼:
/**
* 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產(chǎn)生的周期工作線程洒忧,如果遇到任何意外則會停止后續(xù)執(zhí)行;
如果執(zhí)行的Runnable線程任務(wù)沒有加異常烤惊,則會出現(xiàn)只執(zhí)行一次則線程停止的問題乔煞!特別引起重視!
三柒室、總結(jié)
1渡贾、獲取一個(gè)線程池定時(shí)任務(wù)異常關(guān)閉的小tip,注意任何心跳類希望一直保持線程定時(shí)任務(wù)雄右,為保證線程可靠性空骚,最好捕獲異常進(jìn)行相關(guān)保護(hù)纺讲;
2、靈感源于代碼囤屹,因此切忌遇到問題要關(guān)注代碼底層實(shí)現(xiàn)熬甚,學(xué)會看jdk文檔接口的詳細(xì)說明,可以少走很多彎路肋坚;
3乡括、學(xué)習(xí)ScheduledFuture這個(gè)返回:
- 繼承了Delayed, Future<V>兩個(gè)接口
- long getDelay(TimeUnit unit);支持返回線程任務(wù)的最近間隔時(shí)間
- future提供的cancel、get等方法用于任務(wù)取消或者獲取智厌,作用也很重要诲泌,注意學(xué)習(xí)用法
四、測試代碼
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();
}
*/
}
}
}