代码:
/******
* description: 要求框架使用者实现的接口
*******/
public interface ITaskProcess<T, R> {
/**
* @param data 调用业务方法需要使用到的数据
* @return 方法执行后业务方法的结果
*/
TaskResult<R> taskExecute(T data);
}一
/******
* description: 存放到队列的元素
*******/
public class ItemVo<T> implements Delayed {
private long activeTime; //到期时间,单位毫秒
private T date;
//activeTime是个过期时长
public ItemVo(long activeTime, T date) {
super();
this.activeTime = TimeUnit.NANOSECONDS.convert(activeTime,
TimeUnit.MICROSECONDS) + System.nanoTime();//将传入的时长转换为超时的时刻
this.date = date;
}
public long getActiveTime() {
return activeTime;
}
public T getDate() {
return date;
}
//返回元素的剩余时间
@Override
public long getDelay(TimeUnit unit) {
long d = unit.convert(this.activeTime - System.nanoTime(), TimeUnit.NANOSECONDS);
return d;
}
@Override
public int compareTo(Delayed o) {
long d = getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
return (d == 0)? 0: ((d>0)? 1: -1);
}
}
/******
* description: 提交给框架执行的工作实体类,工作:表示本批次需要处理的同性质任务(Task)的一个集合
*******/
public class JobInfo<R> {
//任务名
private final String jobName;
//工作的任务个数
private final int jobLength;
//工作的任务处理器
private final ITaskProcess<?, ?> taskProcess;
//成功处理的任务数
private final AtomicInteger successCount;
//已处理的任务数
private final AtomicInteger taskProcessCount;
//结果队列,拿结果从头拿,放结果从尾部放
private final LinkedBlockingDeque<TaskResult<R>> taskDetailQueue;
//工作的完成保存时间,超过这个时间从缓存中清除
private final long expireTime;
public JobInfo(String jobName, int jobLength, ITaskProcess<?, ?> taskProcess, long expireTime) {
this.jobName = jobName;
this.jobLength = jobLength;
this.taskProcess = taskProcess;
this.expireTime = expireTime;
this.successCount = new AtomicInteger(0);
this.taskProcessCount = new AtomicInteger(0);
this.taskDetailQueue = new LinkedBlockingDeque<>(jobLength);
;
}
//返回任务处理器
public ITaskProcess<?, ?> getTaskProcess() {
return taskProcess;
}
//返回成功处理的任务数
public int getSuccessCount() {
return successCount.get();
}
//返回已处理的任务数
public int getTaskProcessCount() {
return taskProcessCount.get();
}
//返回任务失败个数
public int getFailCount() {
return taskProcessCount.get() - successCount.get();
}
public String getTotalProcess() {
return "Success[" + successCount.get() + "]/Current[" + taskProcessCount.get() + "] Total[" + jobLength + "]";
}
//获取每个任务的处理详情
public List<TaskResult<R>> getTaskDetail() {
LinkedList<TaskResult<R>> list = new LinkedList<>();
TaskResult<R> taskResult;
while ((taskResult = taskDetailQueue.pollFirst()) != null) {
list.add(taskResult);
}
return list;
}
public void addTaskResult(TaskResult<R> taskResult, CheckJobProcesser checkJobProcesser) {
if (TaskResultType.Success.equals(taskResult.getResultType())) {
successCount.incrementAndGet();
}
taskDetailQueue.addLast(taskResult);
taskProcessCount.incrementAndGet();
if (taskProcessCount.get() == jobLength) {
checkJobProcesser.putJob(jobName, expireTime);
}
}
}
/******
* description: 方法本身运行是否正确的结果类型
*******/
public enum TaskResultType {
//方法成功执行并返回了业务人员需要的结果
Success,
//方法成功执行但是返回的是业务人员不需要的结果
Failure,
//方法执行抛出了Exception
Exception;
}
public class TaskResult<T> {
//方法本身运行是否正确的结果类型
private final TaskResultType resultType;
//方法的业务结果数据
private final T returnValue;
//存在方法失败的原因
private final String reason;
public TaskResult(TaskResultType resultType, T returnValue, String reason) {
this.resultType = resultType;
this.returnValue = returnValue;
this.reason = reason;
}
//方便业务人员使用,这个构造方法表示业务方法执行成功的返回结果
public TaskResult(TaskResultType resultType, T returnValue) {
this.resultType = resultType;
this.returnValue = returnValue;
this.reason = "Success";
}
public TaskResultType getResultType() {
return resultType;
}
public T getReturnValue() {
return returnValue;
}
public String getReason() {
return reason;
}
@Override
public String toString() {
return "TaskResult{" +
"resultType=" + resultType +
", returnValue=" + returnValue +
", reason='" + reason + '\'' +
'}';
}
}
/******
* description: 任务完成后,在一定的时间供查询,之后为释放资源节约内存,需要定期处理过期的任务
*******/
public class CheckJobProcesser {
static {
Thread thread = new Thread(new FetchJob());
thread.setDaemon(true);
thread.start();
System.out.println("开启任务过期检查守护线程.............");
}
//存放已完成任务等待过期的队列
private static DelayQueue<ItemVo<String>> queue = new DelayQueue<>();
//单例模式
private CheckJobProcesser(){}
private static class ProcessHolder{
public static CheckJobProcesser processer = new CheckJobProcesser();
}
public static CheckJobProcesser getInstance() {
return ProcessHolder.processer;
}
//处理队列中到期任务的实行
private static class FetchJob implements Runnable {
@Override
public void run() {
while (true) {
try {
//拿到已经过期的任务
ItemVo<String> item = queue.take();
String jobName = item.getDate();
PendingJobPool.getMap().remove(jobName);
System.out.println(jobName + " is out of date, remove from map");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//任务完成后,放入队列,经过expireTime时间,从整个框架中移除
public void putJob(String jobName, long expireTime) {
ItemVo<String> item = new ItemVo<>(expireTime, jobName);
queue.offer(item);
System.out.println("job[" + jobName + "已经放入了过期检查缓存,过期时长:"+expireTime);
}
}
/******
* 框架的主体类,也是调用者主要使用的类
*******/
public class PendingJobPool {
//开启的线程数,按CPU的核心数来定
private static final int THREAD_COUNTS = Runtime.getRuntime().availableProcessors();
//任务队列
private static BlockingQueue<Runnable> taskQueue = new ArrayBlockingQueue<>(5000);
//线程池,固定大小,有界队列
private static ExecutorService taskExecutor = new ThreadPoolExecutor(THREAD_COUNTS, THREAD_COUNTS,
60, TimeUnit.SECONDS, taskQueue);
//job的存放容器
private static ConcurrentHashMap<String, JobInfo<?>> jobInfoMap = new ConcurrentHashMap<>();
public static Map<String, JobInfo<?>> getMap() {
return jobInfoMap;
}
private static CheckJobProcesser checkJobProcesser = CheckJobProcesser.getInstance();
//单例模式-----
private PendingJobPool() {
}
private static class JobPoolHolder {
public static PendingJobPool pool = new PendingJobPool();
}
public static PendingJobPool getInstance() {
return JobPoolHolder.pool;
}
//单例模式-----
@SuppressWarnings("unchecked")
private <R> JobInfo<R> getJob(String jobName) {
JobInfo<R> jobInfo = (JobInfo<R>)jobInfoMap.get(jobName);
if (null == jobInfo) {
throw new RuntimeException(jobName + "是个非法任务");
}
return jobInfo;
}
//调用者注册工作,如工作名,任务的处理器等
public <R> void registerJob(String jobName, int jobLength,
ITaskProcess<?, ?> taskProcess, long expireTime) {
JobInfo<R> jobInfo = new JobInfo<>(jobName, jobLength, taskProcess, expireTime);
if (null != jobInfoMap.putIfAbsent(jobName, jobInfo)) {
throw new RuntimeException(jobName + "已经注册了");
}
}
//调用者提交工作中的任务
public <T,R> void putTask(String jobName, T t) {
JobInfo<R> jobInfo = getJob(jobName);
PendingTask<T, R> task = new PendingTask<>(jobInfo, t);
taskExecutor.execute(task);
}
//获得每个任务的处理详情
public <R>List<TaskResult<R>> getTaskDetail(String jobName) {
JobInfo<R> jobInfo = getJob(jobName);
return jobInfo.getTaskDetail();
}
//获得工作的整体处理进度
public <R> String getTaskProgess(String jobName) {
JobInfo<Object> jobInfo = getJob(jobName);
return jobInfo.getTotalProcess();
}
//对工作中的任务进行包装,提交给线程池使用,并处理任务的结果,写入缓存以供查询
private static class PendingTask<T, R> implements Runnable {
private JobInfo<R> jobInfo;
private T processData;
public PendingTask(JobInfo<R> jobInfo, T processData) {
super();
this.jobInfo = jobInfo;
this.processData = processData;
}
@SuppressWarnings("unchecked")
@Override
public void run() {
R r = null;
ITaskProcess<T, R> taskProcess = (ITaskProcess<T, R>)jobInfo.getTaskProcess();
TaskResult<R> result = null;
try {
//调用业务人员实现的具体方法
result = taskProcess.taskExecute(processData);
//做检查,防止开发人员处理不当
if (result == null) {
result = new TaskResult<R>(TaskResultType.Exception, r, "result is null");
}
if (result.getResultType() == null) {
if (result.getReason() == null) {
result = new TaskResult<R>(TaskResultType.Exception, r, "reason is null");
} else {
result = new TaskResult<R>(TaskResultType.Exception, r,
"result is null,but reason:" + result.getReason());
}
}
} catch (Exception e) {
e.printStackTrace();
result = new TaskResult<R>(TaskResultType.Exception, r, e.getMessage());
} finally {
jobInfo.addTaskResult(result, checkJobProcesser);
}
}
}
}
public class MyTask implements ITaskProcess<Integer, Integer> {
@Override
public TaskResult<Integer> taskExecute(Integer data) {
Random random = new Random();
int flag = random.nextInt(500);
try {
Thread.sleep(flag);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (flag <= 300) {//正常处理情况
int value = data.intValue() + flag;
return new TaskResult<Integer>(TaskResultType.Success, value);
} else if (flag > 301 && flag <= 400) { //处理失败的情况
return new TaskResult<Integer>(TaskResultType.Failure, -1, "Failure");
} else { //发生异常的情况
try{
throw new RuntimeException("异常发生了!!");
} catch (Exception e) {
return new TaskResult<Integer>(TaskResultType.Exception,-1,e.getMessage());
}
}
}
}
public class AppTest {
private final static String JOB_NAME = "计算数值任务";
private final static int JOB_LENGTH = 1000;
//查询任务进度的线程
private static class QueryResult implements Runnable {
private PendingJobPool pool;
public QueryResult(PendingJobPool pool) {
this.pool = pool;
}
@Override
public void run() {
int i = 0; //查询次数
while (i < 350) {
List<TaskResult<Object>> taskDetail = pool.getTaskDetail(JOB_NAME);
if (!taskDetail.isEmpty()) {
System.out.println(pool.getTaskProgess(JOB_NAME));
System.out.println(taskDetail);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
i ++;
}
}
}
public static void main(String[] args) {
MyTask myTask = new MyTask();
//拿到框架的实例
PendingJobPool pool = PendingJobPool.getInstance();
//注册job
pool.registerJob(JOB_NAME, JOB_LENGTH, myTask, 1000 * 5);
Random random = new Random();
for (int i = 0; i < JOB_LENGTH; i++) {
//依次推入Task
pool.putTask(JOB_NAME, random.nextInt(1000));
}
Thread query = new Thread(new QueryResult(pool));
query.start();
}
}