文章目录
- ScheduledThreadPoolExecutor
- timer(不建议用)
- ScheduledThreadPoolExecutor
- 处理异常
- 应用
ScheduledThreadPoolExecutor
timer(不建议用)
timer也可以进行延迟运行,但是会有很多问题。
比如task1运行时间超过task2延迟时间。
@Slf4j(topic = "c.Main")
public class Main {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task1 = new TimerTask() {
@Override
public void run() {
log.debug("task 1");
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
TimerTask task2 = new TimerTask() {
@Override
public void run() {
log.debug("task 2");
}
};
log.debug("start...");
timer.schedule(task1, 1000);
timer.schedule(task2, 1000);
}
}
当task1出异常,task2不会运行。
ScheduledThreadPoolExecutor
Executors就可以创建。
延迟执行:
@Slf4j(topic = "c.Main")
public class Main {
public static void main(String[] args) {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.schedule(() -> {
log.debug("task1");
int i = 1 / 0; // 模拟异常
}, 1, TimeUnit.SECONDS);
scheduledExecutorService.schedule(() -> {
log.debug("task2");
}, 1, TimeUnit.SECONDS);
}
}
可以看出通过控制线程数可以解决timer的缺点。
同时出现异常也不会影响其他任务运行。
定时运行:
@Slf4j(topic = "c.Main")
public class Main {
public static void main(String[] args) {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
log.debug("start...");
scheduledExecutorService.scheduleAtFixedRate(() -> {
log.debug("running...");
}, 1, 1, TimeUnit.SECONDS); // 每隔1s反复执行
}
}
处理异常
try catch
ExecutorService pool = Executors.newFixedThreadPool(1);
pool.submit(() -> {
try {
log.debug("task1");
int i = 1 / 0;
} catch (Exception e) {
log.error("error:", e);
}
});
通过返回值判断
ExecutorService pool = Executors.newFixedThreadPool(1);
Future<Boolean> f = pool.submit(() -> {
log.debug("task1");
int i = 1 / 0; // 模拟异常
return true;
});
log.debug("result:{}", f.get());
若正常执行返回true,
若出现异常get会返回异常信息。
应用
每周四定时运行
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 获得当前时间
LocalDateTime now = LocalDateTime.now();
// 获取本周四 18点时间
LocalDateTime startTime =
now.with(DayOfWeek.THURSDAY).withHour(18).withMinute(0).withSecond(0).withNano(0);
// 如果当前时间已经超过 本周四 那么找下周四
if(now.compareTo(startTime) >= 0) {
startTime = startTime.plusWeeks(1);
}
// 计算时间差,延时执行时间
long initialDelay = Duration.between(now, startTime).toMillis();
// 执行间隔 1周
long period = 1000 * 60 * 60 * 24 * 7;
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
executor.scheduleAtFixedRate(() -> {
System.out.println("running..");
}, initialDelay, period, TimeUnit.MILLISECONDS);
}
}