java工具类-优雅等待所有任务完成再停机
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class AppUtil {
//0 没任务在执行 > 1 有任务在执行 ,奇数时app已结束。
//最大只支持到30个不同任务。
//同一个任务只支持单线程。
public final AtomicInteger TASK_RUN = new AtomicInteger(0);
//a必须是2的n次方且n>1
public boolean addTask(int a) {
if(a > 1 && (a & (a - 1)) == 0) {
//不允许程序已经结束了,还在跑任务。
if(TASK_RUN.get() % 2 == 1) {
return false;
}
//尝试添加任务
if(TASK_RUN.addAndGet(a) % 2 == 1) {
//任务添加失败,回滚。
deleteTask(a);
return false;
}
return true;
}
throw new RuntimeException("传入的a不是大于1且是2的n次方的数:" + a);
}
public void deleteTask(int a) {
TASK_RUN.addAndGet(-a);
}
public void stopApp() {
TASK_RUN.addAndGet(1);
}
/**
* 必须要保证所有任务都要在指定时间内能结束。
*/
public void waitTaskFinally(int tryLimit) {
int i = 0;
while (true) {
if(TASK_RUN.get() == 1) {
break;
}
if(i++ >= tryLimit) {
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
//如果这里被中断的概率大,就直接不往外抛异常。
throw new RuntimeException(e);
}
}
}
public void run(Runnable run, int a) {
boolean lock = addTask(a);
try {
if(!lock) return;
run.run();
} finally {
if(lock) deleteTask(a);
}
}
public static void main(String[] args) throws InterruptedException {
AppUtil app = new AppUtil();
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
pool.scheduleAtFixedRate(() -> {
app.run(() -> System.out.println("处理任务one: " + System.currentTimeMillis()), 2);
}, 1, 1, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(() -> {
app.run(() -> System.out.println("处理任务two: " +System.currentTimeMillis()), 4);
}, 1, 2, TimeUnit.SECONDS);
Thread.sleep(10000);
app.stopApp();
app.waitTaskFinally(50);
System.out.println("结束:"+ System.currentTimeMillis() + " " + app);
pool.shutdown();
}
@Override
public String toString() {
return "AppUtil{" +
"TASK_RUN=" + TASK_RUN +
'}';
}
}
使用方式:
public class ActivityApplication {
public static final AppUtil APP_UTIL = new AppUtil();
public static void main(String[] args) {
SpringApplication.run(ActivityApplication.class, args);
log.info("=============system default timeZone: {}", TimeZone.getDefault());
log.info("=============system default zoneId: {}", ZoneId.systemDefault());
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
log.info("收到终止信号,当前标记:appStop: {}", APP_UTIL);
APP_UTIL.stopApp();
//分50次,共等5秒。
//这里如果能保证了在运行中的任务在5秒内能结束的话,就不会被强杀。
APP_UTIL.waitTaskFinally(50);
log.info("收到终止信号,最新标记:appStop: {}", APP_UTIL);
}));
}
}
浙公网安备 33010602011771号