Java 自定义线程池的任务

  在《Java 自定义线程池的线程工厂》一文中介绍了如何优雅地自定义线程工厂,本文介绍如何自定义线程池的任务,并拿到返回值。

  首先自定义一个任务类,实现Callable接口,重写call函数,定义其返回类型为Integer。

import java.util.concurrent.Callable;

public class CalcTask implements Callable<Integer> {

    private int num;
    public CalcTask(int num) {
        this.num = num;
    }

    @Override
    public Integer call() throws Exception {
        doSth();
        // 定义求和变量
        return sum(num);
    }

    private Integer sum(Integer num) {
        // 定义求和变量
        int result = 0;
        for (int i = 1; i <= num; i++) {
            result += i;
        }
        return result;
    }

    private void doSth() {
        System.out.println("do something");
    }

}

  创建任务类的优势是在自定义请求报文和返回报文同时,可以处理超级复杂的业务逻辑,解决在线程池主体函数所在类中代码量非常多的问题。下面构建线程池主体函数,用于分别计算1-100和1-200的值:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class ThreadPoolTest {

    /**
     * 线程池创建提交任务——java
     * 用线程池分别计算1-100和1-200的值
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 创建线程池对象并指定线程数量
        ExecutorService tp = Executors.newFixedThreadPool(2);
        List<Integer> results  = new ArrayList<>();

        // 创建任务实现对象
        FutureTask<Integer> futureTask100 = new FutureTask<>(new CalcTask(100));
        FutureTask<Integer> futureTask200 = new FutureTask<>(new CalcTask(200));
        // 使用submit开启两个任务
        Future<Integer> f1 = (Future<Integer>) tp.submit(futureTask100);// 5050
        Future<Integer> f2 = (Future<Integer>) tp.submit(futureTask200); // 20100
        results.add(f1.get());
        System.out.println("任务返回值依次拿回,阻塞中。。。");
        results.add(f2.get());
        System.out.println(results);
        // 销毁线程池
        tp.shutdown();
    }

}

  这里通过get方法获取执行结果,但该方法会阻塞直到任务返回结果。

posted @ 2021-12-19 12:25  楼兰胡杨  阅读(223)  评论(0编辑  收藏  举报