Future 模式搭配线程池更配哦

 2023-02-06
原文作者:蒋先森 原文地址:https://jlj98.top/

如果本文有错,希望在下面的留言区指正。

在开篇,先提出一个问题,在Java中,通过继承 Thread 或者实现 Runable 创建一个线程的时候,如何获取该线程的返回结果呢?

在并发编程中,使用非阻塞模式的时候,就是出现上面的问题。这个时候就需要用到这次所讲的内容了——Future。

Future 主要功能

    public interface Future<V> {
    
        //使用该方法来取消一个任务,若取消成功,则返回true,否则返回false
        boolean cancel(boolean mayInterruptIfRunning);
    
        //判断任务是否已经取消
        boolean isCancelled();
    
        //判断任务是否已经完成
        boolean isDone();
        
        //当任务结束返回一个结果,如果调用时,为返回结果,则阻塞
        V get() throws InterruptedException, ExecutionException;
    
        //在指定时间内获取指定结果,如果没有获取,则返回null
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }

Future 例子

    public class FutureTest {
    
        public static void main(String[] args) {
            ExecutorService executor = Executors.newSingleThreadExecutor();
            Task task = new Task();
            Future<Integer> result = executor.submit(task);
            executor.shutdown();
    
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
    
            System.out.println("主线程在执行任务");
    
            try {
                System.out.println("task运行结果" + result.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
    
            System.out.println("所有任务执行完毕");
        }
    
    }
    public class Task implements Callable<Integer> {
    
        @Override
        public Integer call() throws Exception {
    
            System.out.println("子线程在进行计算");
            Thread.sleep(3000);
            int sum = 0;
            for (int i = 0; i < 100; i++)
                sum += i;
            return sum;
        }
    }

Future 适用场景

在之前的一篇关于线程池中,详细介绍了Java的一些线程池知识点。那么对于使用线程池,除了管理线程资源外,如何能够实现节约时间呢?

比如现在一个请求中,给前端的返回结果,需要通过查询A、B、C,最后返回给前端,这三个查询分别耗时 10ms、20ms、10ms。如果正常的查询需要耗时40ms(忽略别的影响查询时间的因素)。但是如果把这三个查询交给线程池进行异步查询,那么,它的最终耗时是由最大耗时的那个查询决定的,这时就会发现查询变快了,只耗时20ms。

但是使用线程池的时候,这就和上面一开始的问题类似了,如何去获取线程池返回的结果。线程池代码Reference