Java并发编程之任务提交与管理

在这里插入图片描述代码:

/******
 * 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();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值