com.fishlikewater.schedule.client.executor.ScheduleExecutor Maven / Gradle / Ivy
The newest version!
package com.fishlikewater.schedule.client.executor;
import com.alibaba.fastjson.JSON;
import com.fishlikewater.schedule.client.kit.ScheduleJobContext;
import com.fishlikewater.schedule.common.ScheduleJob;
import com.fishlikewater.schedule.common.entity.MessageProbuf;
import com.fishlikewater.schedule.common.entity.TaskDetail;
import com.fishlikewater.schedule.common.kit.JsonFilter;
import com.fishlikewater.schedule.common.kit.NamedThreadFactory;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author zhangx
* @version V1.0
* @mail [email protected]
* @ClassName ScheduleExecutor
* @Description
* @date 2018年12月26日 14:32
**/
@Slf4j
public class ScheduleExecutor {
private AtomicInteger stat = new AtomicInteger(0);
private Thread thread;
public static ScheduleExecutor getInstance(){
return ScheduleExecutorBuild.scheduleExecutor;
}
private static class ScheduleExecutorBuild{
private static ScheduleExecutor scheduleExecutor = new ScheduleExecutor();
}
private static final int cpuNum = Runtime.getRuntime().availableProcessors();
public static final ExecutorService executor = new ThreadPoolExecutor(cpuNum*4, cpuNum*10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(100000), new NamedThreadFactory("schedule-executor@"));//CPU核数4-10倍
/**
* 客户端任务执行器
* @param channel
* @param taskDetail
*/
public void excutor(Channel channel, TaskDetail taskDetail){
ScheduleExecutor.executor.submit(() ->{
try {
ScheduleJob scheduleJob = taskDetail.getScheduleJob();
taskDetail.setExecutorTime(System.currentTimeMillis());
scheduleJob.run();
/** 通知执行完成*/
taskDetail.setExecutorResult(true);
MessageProbuf.Message message = MessageProbuf.Message.newBuilder()
.setBody(JSON.toJSONString(taskDetail, JsonFilter.sendServerResultFilter))
.setType(MessageProbuf.MessageType.RESULT)
.setExtend(ScheduleJobContext.getInstance().getAppName())
.build();
channel.writeAndFlush(message);
}catch (Exception e){
log.warn("excutor job 【{}】 fail", taskDetail.getDesc());
/** 通知执行失败*/
taskDetail.setExecutorResult(false);
MessageProbuf.Message message = MessageProbuf.Message.newBuilder()
.setBody(JSON.toJSONString(taskDetail, JsonFilter.sendServerResultFilter))
.setType(MessageProbuf.MessageType.RESULT)
.setExtend(ScheduleJobContext.getInstance().getAppName())
.build();
channel.writeAndFlush("");
}
});
}
/**
* 重置队列
*/
public void resetQueue(){
List taskDetailList = ScheduleJobContext.getInstance().getCurrentJobList();
/** 任务添加到队列中*/
long currentTimeMillis = System.currentTimeMillis();
for (TaskDetail taskDetail : taskDetailList) {
long next = taskDetail.getCronSequenceGenerator().next(currentTimeMillis);
taskDetail.setNextTime(next);
}
}
/**
* 客户端队列执行器
*/
public void clientExcutor(){
resetQueue();
List taskDetailList = ScheduleJobContext.getInstance().getCurrentJobList();
thread = new Thread() {
@Override
public void run() {
while (true){
try {
long curTimeMillis = System.currentTimeMillis();
taskDetailList.stream().filter(t -> t.isUse() && t.getNextTime() <= curTimeMillis)
.forEach(t -> {
ScheduleExecutor.executor.submit(() -> {
t.getScheduleJob().run();
});
long next = t.getCronSequenceGenerator().next(System.currentTimeMillis());
t.setNextTime(next);
});
/** 优化线程睡眠机制,若长时间无任务,避免频繁循环刷新*/
Optional first = taskDetailList.stream().sorted().findFirst();
if(first.isPresent()){
long timeMillis = System.currentTimeMillis();
long nextTime = first.get().getNextTime();
if ((nextTime-timeMillis) >5*60*1000){ //长时间无job 保证5分钟刷一次
Thread.sleep(5*60*1000l);
}else if ((nextTime-timeMillis) > 1000 && (nextTime-timeMillis)<=5*60*1000){
Thread.sleep(nextTime-timeMillis);
}else {
Thread.sleep(1000l);
}
}else {
Thread.sleep(5*60*1000);//任务为空的时候线程5分钟刷一次
}
}catch (Exception e){
if(thread.isAlive()){
boolean interrupted = thread.isInterrupted();
if(interrupted){
thread.start();
}
}else {
thread.start();
}
}
}
}
};
thread.setDaemon(true);
thread.start();
stat.set(1);
}
/**
* 客户端队列执行器
*//*
@Deprecated
public void beginJob(){
resetQueue();
if(stat.get() == 0){
log.info("actuator starts execution...");
long sleepTime = ScheduleJobContext.getInstance().getSleepTime();
thread = new Thread() {
@Override
public void run() {
while (true) {
try {
long curTimeMillis = System.currentTimeMillis();
*//** 从队列中取出任务 放到线程池中去 执行*//*
TaskDetail taskDetail = TaskQueue.peek();
if (taskDetail != null) {
if (curTimeMillis >= taskDetail.getNextTime()) {
ScheduleExecutor.executor.submit(() -> {
log.info("begin task:{}", taskDetail.getDesc());
taskDetail.getScheduleJob().run();
log.info("end task:{}", taskDetail.getDesc());
*//** 执行完成后 添加下次任务到队列*//*
long cTimeMillis = System.currentTimeMillis();
long next = taskDetail.getCronSequenceGenerator().next(cTimeMillis);
taskDetail.setNextTime(next);
TaskQueue.remove();
TaskQueue.add(taskDetail);
});
}
}
Thread.sleep(sleepTime);
}catch (Exception e){
if(thread.isAlive()){
boolean interrupted = thread.isInterrupted();
if(interrupted){
thread.start();
}
}else {
thread.start();
}
}
}
}
};
thread.setDaemon(true);
thread.start();
stat.set(1);
}
}*/
}