Future接口的优缺点

简介: JUC学习

Future接口的优缺点

优点

future+线程池异步多线程任务配合,能显著提高程序的执行效率。

case:

public class FutureThreadPoolDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //3个任务,目前只有一个线程main来处理,耗时多少?
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        long startTime = System.currentTimeMillis();
        FutureTask<String> task1 =  new FutureTask<String>(()->{
           try{ TimeUnit.MILLISECONDS.sleep(500);}catch(InterruptedException e) {e.printStackTrace();}
           return "task1 over";
        });
        threadPool.submit(task1);
        FutureTask<String> task2 =  new FutureTask<String>(()->{
            try{ TimeUnit.MILLISECONDS.sleep(300);}catch(InterruptedException e) {e.printStackTrace();}
            return "task2 over";
        });
        threadPool.submit(task2);
        System.out.println(task1.get());
        System.out.println(task2.get());
        try{ TimeUnit.MILLISECONDS.sleep(300);}catch(InterruptedException e) {e.printStackTrace();}
        threadPool.shutdown(); //关闭线程池
        long endTime = System.currentTimeMillis();
        System.out.println("----costTime:"+(endTime-startTime)+"毫秒");
        System.out.println(Thread.currentThread().getName()+"\t-------end");
    }
//    private static void m1() {
//        //3个任务,目前只有一个线程main来处理,耗时多少?
//        long startTime = System.currentTimeMillis();
//        try{ TimeUnit.MILLISECONDS.sleep(500);}catch(InterruptedException e) {e.printStackTrace();}
//        try{ TimeUnit.MILLISECONDS.sleep(300);}catch(InterruptedException e) {e.printStackTrace();}
//        try{ TimeUnit.MILLISECONDS.sleep(300);}catch(InterruptedException e) {e.printStackTrace();}
//        long endTime = System.currentTimeMillis();
//        System.out.println("----costTime:"+(endTime-startTime)+"毫秒");
//        System.out.println(Thread.currentThread().getName()+"\t-------end");
//    }
}

缺点

  1. get()方法容易引起阻塞,如果没有计算完成,容易导致程序阻塞。如下程序:
/**
 * @author ygf
 * @date 2022/9/18 15:31
 * 1.get容易导致阻塞,一般建议放到程序后面,一旦调用不见不散,非要等到结果才会离开,不管计算是否完成,容易引起阻塞。
 * 2.假如我不愿意等待很长时间,我希望可以过时不候,到时间了可以自动离开用:task1.get(3,TimeUnit.SECONDS)
 */
public class FutureAPIDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        FutureTask<String> task1 =  new FutureTask<String>(()->{
            try{ TimeUnit.MILLISECONDS.sleep(5000);}catch(InterruptedException e) {e.printStackTrace();}
            return "task1 over";
        });
        Thread t1 =  new Thread(task1,"t1");
        t1.start();
//        System.out.println(task1.get()); //调用get(),就会阻塞,不见不散,非要等到结果才会离开
        System.out.println(task1.get(3,TimeUnit.SECONDS));
        System.out.println(Thread.currentThread().getName()+"----忙其他任务了");
    }
}
  1. isDone()轮询 容易引起cpu空转,耗费更多的资源
public class FutureAPIDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        FutureTask<String> task1 =  new FutureTask<String>(()->{
            try{ TimeUnit.MILLISECONDS.sleep(5000);}catch(InterruptedException e) {e.printStackTrace();}
            return "task1 over";
        });
        Thread t1 =  new Thread(task1,"t1");
        t1.start();
//        System.out.println(task1.get()); //调用get(),就会阻塞,不见不散,非要等到结果才会离开
//        System.out.println(task1.get(3,TimeUnit.SECONDS));
        System.out.println(Thread.currentThread().getName()+"----忙其他任务了");
//        System.out.println(task1.get());
        while (true){
            if(task1.isDone()){
                System.out.println(task1.get());
                break;
            }else{
                try{ TimeUnit.MILLISECONDS.sleep(300);}catch(InterruptedException e) {e.printStackTrace();}
                System.out.println("正在处理中.......");
            }
        }
    }
}

返回结果

image.png

总结

Future对于结果的获取不是很友好,这就是CompletableFuture的诞生的理由了。

目录
打赏
0
0
0
0
67
分享
相关文章
Future与FutureTask源码解析,接口阻塞问题及解决方案
【11月更文挑战第5天】在Java开发中,多线程编程是提高系统并发性能和资源利用率的重要手段。然而,多线程编程也带来了诸如线程安全、死锁、接口阻塞等一系列复杂问题。本文将深度剖析多线程优化技巧、Future与FutureTask的源码、接口阻塞问题及解决方案,并通过具体业务场景和Java代码示例进行实战演示。
73 3
|
4月前
|
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
63 1
|
9月前
|
Java并发编程:理解并使用Future和Callable接口
【2月更文挑战第25天】 在Java中,多线程编程是一个重要的概念,它允许我们同时执行多个任务。然而,有时候我们需要等待一个或多个线程完成,然后才能继续执行其他任务。这就需要使用到Future和Callable接口。本文将深入探讨这两个接口的用法,以及它们如何帮助我们更好地管理多线程。
并发编程系列教程(09) - Callable与Future模式
并发编程系列教程(09) - Callable与Future模式
63 0
异步编程 - 06 基于JDK中的Future实现异步编程(中)_CompletableFuture源码解析
异步编程 - 06 基于JDK中的Future实现异步编程(中)_CompletableFuture源码解析
77 0
JUC基础(二)—— Future接口 及其实现
JUC基础(二)—— Future接口 及其实现
174 1
创建多线程的方式三:实现Callable接口。
创建多线程的方式三:实现Callable接口。
80 0
【JUC基础】15. Future模式
Future 模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用。当我们需要调用一个函数方法时,如果这个函数执行得很慢,那么我们就要进行等待。但有时候,我们可能并不急着要结果。因此,我们可以让被调者立即返回,让它在后台慢慢处理这个请求。对于调用者来说,则可以先处理一些其他任务,在真正需要数据的场合再去尝试获得需要的数据。
163 0
【JUC基础】15. Future模式