我的需求是间隔1s,去执行我的Thread,无论上次是否成功失败,间隔1s后,就要去执行。
public class ThreadTimerExecutor {
public static ScheduledThreadPoolExecutor threadPoolExecutor;
public static final String THREAD_NAME = "set-timer-%s";
static {
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat(ThreadTimerExecutor.THREAD_NAME).build();
ThreadTimerExecutor.threadPoolExecutor = new ScheduledThreadPoolExecutor(2, namedThreadFactory);
}
/**
* 设置定时执行
*
* @param runnable
* @param delay
*/
public static void setSchedule(Runnable runnable, Long delay){
threadPoolExecutor.scheduleAtFixedRate(runnable, 0, delay, TimeUnit.MILLISECONDS);
}
}
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit)
参数对应含义:command为被执行的线程;initialDelay为初始化后延时执行时间;period为两次开始执行最小间隔时间;unit为计时单位。
业务逻辑处理间隔时间小于1000。
// 大致代码
public class Test {
public static Long readTimeInterval = Calendar.getInstance().getTimeInMillis();
public static void main(String[] args) {
setSchedule(() -> {
long nowTime = Calendar.getInstance().getTimeInMillis();
long subTime = nowTime - readTimeInterval;
// 这里的1_000和下面period联动才能达到效果
if (subTime >= 1000) {
readTimeInterval = nowTime;
System.out.println("subTime: " + subTime);
try {
// 模拟业务处理
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, 1000L);
}
}
日志:
23:08:21.355 [set-timer-8] INFO subTime: 1000
23:08:22.356 [set-timer-8] INFO subTime: 1002
23:08:24.344 [set-timer-8] INFO subTime: 1988
23:08:25.351 [set-timer-3] INFO subTime: 1007
23:08:26.352 [set-timer-3] INFO subTime: 1001
23:08:27.355 [set-timer-3] INFO subTime: 1003
23:08:29.343 [set-timer-3] INFO subTime: 1988
23:08:30.351 [set-timer-3] INFO subTime: 1008
23:08:32.343 [set-timer-3] INFO subTime: 1992
若业务处理时间大于等于设置的period间隔时间附近值时,时间就会很平均
// 大致代码
public class Test {
public static Long readTimeInterval = Calendar.getInstance().getTimeInMillis();
public static void main(String[] args) {
setSchedule(() -> {
long nowTime = Calendar.getInstance().getTimeInMillis();
long subTime = nowTime - readTimeInterval;
if (subTime >= 1000) {
readTimeInterval = nowTime;
System.out.println("subTime: " + subTime);
try {
// 模拟业务处理
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, 1000L);
}
}
日志:
23:38:22.489 subTime: 1026
23:38:23.492 subTime: 1075
23:38:24.495 subTime: 1002
23:38:25.496 subTime: 1002
23:38:26.501 subTime: 1005
23:38:27.505 subTime: 1004
23:38:28.511 subTime: 1006
23:38:29.517 subTime: 1006
23:38:30.523 subTime: 1006
23:38:31.528 subTime: 1005
若把逻辑处理时间再加倍加大,时间subTime也会被放大。
scheduleAtFixedRate这个方法实测下来发现设置的周期period时间,去执行调用,但是实际并不是按照周期period去做,当业务处理时间小于周期period时间有时会间隔2s,业务处理时间大于等于周期period附近值时,时间间隔就很平均。
public class ThreadTimerExecutor {
public static ScheduledThreadPoolExecutor threadPoolExecutor;
public static final String THREAD_NAME = "set-timer-%s";
static {
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat(ThreadTimerExecutor.THREAD_NAME).build();
ThreadTimerExecutor.threadPoolExecutor = new ScheduledThreadPoolExecutor(2, namedThreadFactory);
}
/**
* 设置定时执行
*
* @param runnable
* @param delay
*/
public static void setSchedule(Runnable runnable, Long delay){
threadPoolExecutor.scheduleWithFixedDelay(runnable, 0, delay, TimeUnit.MILLISECONDS);
}
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit)
参数对应含义:command为被执行的线程;initialDelay为初始化后延时执行时间;delay为前一次执行结束到下一次执行开始的间隔时间(间隔执行延迟时间);unit为计时单位。
// 大致代码
public class Test {
public static Long readTimeInterval = Calendar.getInstance().getTimeInMillis();
public static void main(String[] args) {
setSchedule(() -> {
long nowTime = Calendar.getInstance().getTimeInMillis();
long subTime = nowTime - readTimeInterval;
// 这里的1_000和下面period联动才能达到效果
if (subTime >= 1000) {
readTimeInterval = nowTime;
System.out.println("subTime: " + subTime);
try {
// 模拟业务处理
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, 1000L);
}
}
日志:
00:28:33.353 subTime: 1300
00:28:34.558 subTime: 1205
00:28:35.764 subTime: 1207
00:28:36.971 subTime: 1207
00:28:38.174 subTime: 1202
00:28:39.382 subTime: 1209
00:28:40.589 subTime: 1207
00:28:41.800 subTime: 1211
00:28:43.009 subTime: 1209
00:28:44.215 subTime: 1206
scheduleWithFixedDelay方法,他会把业务处理时间+delay时间,算在一起,他就更加不是设置的间隔时间执行了。