• 论多线程“分而治之“Future<V>的执行效率


    如果需要多个任务同时进行的,我们用什么方式最方便呢,第一种肯定是同步进行,一个一个进行,这样子肯定最慢的,还有一种就是同时进行,即:"分而治之",使用Future接口。

    一、Future简介

    Future接口是用来获取异步计算结果的,说白了就是对具体的Runnable或者Callable对象任务执行的结果进行获取(get()),取消(cancel()),判断是否完成等操作。我们看看Future接口的源码:

    1. public interface Future {
    2. boolean cancel(boolean mayInterruptIfRunning);
    3. boolean isCancelled();
    4. boolean isDone();
    5. V get() throws InterruptedException, ExecutionException;
    6. V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
    7. }

    方法解析:
    V get() :获取异步执行的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。
    V get(Long timeout , TimeUnit unit) :获取异步执行结果,如果没有结果可用,此方法会阻塞,但是会有时间限制,如果阻塞时间超过设定的timeout时间,该方法将抛出异常。
    boolean isDone() :如果任务执行结束,无论是正常结束或是中途取消还是发生异常,都返回true。
    boolean isCanceller() :如果任务完成前被取消,则返回true。
    boolean cancel(boolean mayInterruptRunning) :如果任务还没开始,执行cancel(...)方法将返回false;如果任务已经启动,执行cancel(true)方法将以中断执行此任务线程的方式来试图停止任务,如果停止成功,返回true;当任务已经启动,执行cancel(false)方法将不会对正在执行的任务线程产生影响(让线程正常执行到完成),此时返回false;当任务已经完成,执行cancel(...)方法将返回false。mayInterruptRunning参数表示是否中断执行中的线程。
    通过方法分析我们也知道实际上Future提供了3种功能:

    (1)能够中断执行中的任务

    (2)判断任务是否执行完成

    (3)获取任务执行完成后额结果。
    但是我们必须明白Future只是一个接口,我们无法直接创建对象,因此就需要其实现类FutureTask登场啦。

    二、实战检验

    我们直接上码,看一下差距:

    1. @Test
    2. public void forkJoinTest() throws ExecutionException, InterruptedException {
    3. long curTime = System.currentTimeMillis();
    4. Future> r1 = ThreadPoolUtils.normalPool.submit(() -> {
    5. List result = new ArrayList<>();
    6. for (int i = 0 ; i < 1000000 ; i++) {
    7. result.add(String.valueOf(i));
    8. }
    9. return result;
    10. });
    11. Future> r2 = ThreadPoolUtils.normalPool.submit(() -> {
    12. List result = new ArrayList<>();
    13. for (int i = 1000000 ; i < 2000000 ; i++) {
    14. result.add(String.valueOf(i));
    15. }
    16. return result;
    17. });
    18. Future> r3 = ThreadPoolUtils.normalPool.submit(() -> {
    19. List result = new ArrayList<>();
    20. for (int i = 2000000 ; i < 3000000 ; i++) {
    21. result.add(String.valueOf(i));
    22. }
    23. return result;
    24. });
    25. List result1 = r1.get();
    26. List result2 = r2.get();
    27. List result3 = r3.get();
    28. System.out.println(System.currentTimeMillis() - curTime);
    29. curTime = System.currentTimeMillis();
    30. List result4 = new ArrayList<>();
    31. for (int i = 0 ; i < 1000000 ; i++) {
    32. result4.add(String.valueOf(i));
    33. }
    34. List result5 = new ArrayList<>();
    35. for (int i = 1000000 ; i < 2000000 ; i++) {
    36. result5.add(String.valueOf(i));
    37. }
    38. List result6 = new ArrayList<>();
    39. for (int i = 2000000 ; i < 3000000 ; i++) {
    40. result6.add(String.valueOf(i));
    41. }
    42. System.out.println(System.currentTimeMillis() - curTime);
    43. }

    执行时间如下:

    由此可见, 多线程"分而治之"Future的执行效率还是很高的

  • 相关阅读:
    基于JAVA校园拓展活动培训管理系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
    c++ 利比亚行动 (libyan)
    如何将高效设计应用于 DAO?
    java计算机毕业设计ssm+vue微空间私人定向共享系统
    计算机竞赛 基于机器视觉的二维码识别检测 - opencv 二维码 识别检测 机器视觉
    如何将 Docsify 项目部署到 CentOS 系统的 Nginx 中
    【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(二)
    C语言打印菱形
    网络安全(黑客)自学笔记
    字符串逆序 C语言
  • 原文地址:https://blog.csdn.net/qq_37284798/article/details/126643366