程序员的日常——多线程一

    前段时间面试,问了一个简单的问题,

           当一个服务需要调用多个外部服务时,调用链比较长,当是同步调用时,将会是多个服务响应时间的综合。而我们使用异步的方式,将会取决于最大响应时间的服务。

比如现在有4个服务,学生服务 1秒,教师服务2秒,班级服务3秒,宿舍服务4秒。我们采用同步调用的话,将花费10秒多。

假设 学生服务和班级服务相互依赖。所以组合起来异步调用花费3秒。教师和宿舍服务组合花费4秒。那么将花费7秒左右。

下面使用简单的代码来模拟下场景。

//任务类

public class Task {

    public List<Integer> studentService(){
        try {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            Thread.sleep(1000);
            return list;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    public List<Integer> teacherService(){
        try {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            Thread.sleep(2000);
            return list;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    public List<Integer> classService(){
        try {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            Thread.sleep(3000);
            return list;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    public List<Integer> dormitoryService(){
        try {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            Thread.sleep(4000);
            return list;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

}
//线程池工具类

public enum PoolThreadUtil {

    Instance;
    private ThreadPoolExecutor threadPoolExecutor;

    PoolThreadUtil() {
        threadPoolExecutor = new ThreadPoolExecutor(4, 4,
                2, TimeUnit.SECONDS, new ArrayBlockingQueue(10));
    }

    private List<Future<Object>> invokeCommands(List<Callable<Object>> callables) {
        try {
            return this.threadPoolExecutor.invokeAll(callables);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }


    public List<Object> execute(List<Callable<Object>> callables) {
        List<Object> resultList = new ArrayList<>();
        List<Future<Object>> futureList = this.invokeCommands(callables);

        try {
            for (Future future : futureList) {
                resultList.add(future.get());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return resultList;
    }

    public void shutDown(){
        this.threadPoolExecutor.shutdown();
    }

}
//客户端调用

    public static void main(String[] args) {
        Test.async();
        Test.sync();
        PoolThreadUtil.Instance.shutDown();
    }

    public static void sync() {
        Task task = new Task();
        List<Object> list = new ArrayList<>();
        Long start = System.currentTimeMillis();
        list.addAll(task.studentService());
        list.addAll(task.classService());
        list.addAll(task.teacherService());
        list.addAll(task.dormitoryService());
        Long end = System.currentTimeMillis();
        System.out.println("sync消耗时间——》" + String.valueOf(end - start) + "ms");
    }

    public static void async() {
        Task task = new Task();
        List<Object> list = new ArrayList<>();
        Long start = System.currentTimeMillis();
        List<Callable<Object>> callables = new ArrayList<>();
        callables.add(() -> {
            return task.studentService();
        });
        callables.add(() -> {
            return task.classService();
        });
        list.addAll(PoolThreadUtil.Instance.execute(callables));

        callables.clear();
        callables.add(() -> {
            return task.teacherService();
        });
        callables.add(() -> {
            return task.dormitoryService();
        });
        list.addAll(PoolThreadUtil.Instance.execute(callables));
        Long end = System.currentTimeMillis();
        System.out.println("async消耗时间——》" + String.valueOf(end - start) + "ms");

    }

异步和同步输出对比

async消耗时间——》7124
sync消耗时间——》10002

总结:从结果可以看出来,多线程的方式确实能提高响应速度,但由于线程的数量不是无限的,所以在设计线城市参数时要考虑业务请求以及队列的大小,线程数太少的话,会造成队列请求数过多,反而会导致响应速度更慢。所以线程池的参数要仔细斟酌。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值