从任务中返回值

import java.util.concurrent.Callable;

public class TaskWithResult implements Callable<String> {

    private int id;
    public TaskWithResult(int id) {
        this.id = id;
    }
    @Override
    public String call() throws Exception {
        return "result of TaskWithResult" + id;
    }
}
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 从任务中产生返回值
 * Runnable是执行工作的独立任务,但是它不返回任何值。如果你希望任务在完成时能够返回一个值,
 * 那么可以实现Callable接口而不是Runnable接口。在Java SE5中引用的Callabel是一种具有类型参数的泛型,
 * 它的参数类型表示的是从方法call()(而不是run)中返回的值,并且必须使用ExecutorService.submit方法调用它
 *
 *
 * submit方法会产生Future对象,它用Callable返回结果的特定类型进行了参数啊。你可以用isDone方法来查询Future是否
 * 已经完成。当任务完成时,它具有一个结果,你可以调用get方法来获取该结果.你也可以不用isDone进行检查就直接调用get,在这种情况下,
 * get将阻塞,直至结果准备就绪。你还可以在视图调用get来获取结果之前,先调用具有超时的get,或者调用isDone来查看任务是否完成。
 *
 * Future 最主要的作用是,比如当做一定运算的时候,运算过程可能比较耗时,
 * 有时会去查数据库,或是繁重的计算,比如压缩、加密等,在这种情况下,
 * 如果我们一直在原地等待方法返回,显然是不明智的,整体程序的运行效率会大大降低。
 * 我们可以把运算的过程放到子线程去执行,再通过 Future 去控制子线程执行的计算过程,
 * 最后获取到计算结果。这样一来就可以把整个程序的运行效率提高,是一种异步的思想。
 *
 * get() 方法:获取结果
 * get 方法最主要的作用就是获取任务执行的结果,该方法在执行时的行为取决于 Callable 任务的状态,可能会发生以下 5 种情况。
 * (1)最常见的就是当执行 get 的时候,任务已经执行完毕了,可以立刻返回,获取到任务执行的结果。
 * (2)任务还没有结果,这是有可能的,比如我们往线程池中放一个任务,线程池中可能积压了很多任务,还没轮到我去执行的时候,就去 get 了,
 * 在这种情况下,相当于任务还没开始;还有一种情况是任务正在执行中,但是执行过程比较长,所以我去 get 的时候,它依然在执行的过程中。
 * 无论是任务还没开始或在进行中,我们去调用 get 的时候,都会把当前的线程阻塞,直到任务完成再把结果返回回来。
 * (3)任务执行过程中抛出异常,一旦这样,我们再去调用 get 的时候,就会抛出 ExecutionException 异常,
 * 不管我们执行 call 方法时里面抛出的异常类型是什么,在执行 get 方法时所获得的异常都是 ExecutionException。
 * (4)任务被取消了,如果任务被取消,我们用 get 方法去获取结果时则会抛出 CancellationException。
 * (5)任务超时,我们知道 get 方法有一个重载方法,那就是带延迟参数的,调用了这个带延迟参数的 get 方法之后,
 * 如果 call 方法在规定时间内正常顺利完成了任务,那么 get 会正常返回;但是如果到达了指定时间依然没有完成任务,
 * get 方法则会抛出 TimeoutException,代表超时了。
 *
 * 2.isDone() 方法:判断是否执行完毕
 * 该方法是用来判断当前这个任务是否执行完毕了。
 *
 * 这个方法如果返回 true 则代表执行完成了;如果返回 false 则代表还没完成。但这里如果返回 true,
 * 并不代表这个任务是成功执行的,比如说任务执行到一半抛出了异常。那么在这种情况下,对于这个 isDone
 * 方法而言,它其实也是会返回 true 的,因为对它来说,虽然有异常发生了,但是这个任务在未来也不会再被执行,
 * 它确实已经执行完毕了。所以 isDone 方法在返回 true 的时候,不代表这个任务是成功执行的,只代表它执行完毕了。
 */
public class CallableDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        ArrayList<Future<String>> futures = new ArrayList<Future<String>>();//多线程开发中的常见的设计模式,它的核心思想是异步调用
        /**
         * 提交一个返回值的任务供执行,并返回一个Future表示任务的待处理结果。的Future的{@code get}方法将返回任务的结果圆满完成。
         * 有三种类型,接返回future,可以阻塞获取线程执行结果,在执行异常时会被异常处理吃掉,不会抛出异常
         * 不抛出异常,仍然显示任务完成,这里isDone标志线程是否执行完,不管有没有异常,只要执行完都是true,不会阻塞队列
         *
         * 使用get()可以看到异常信息
         */
        for (int i = 0; i < 10; i++) {
            futures.add(executorService.submit(new TaskWithResult(i)));
        }

        for (Future<String> future : futures) {
            try {
                System.out.println(future.get());
            } catch (InterruptedException e) {
                System.out.println(e);
                return;
            } catch (ExecutionException e) {
                System.out.println(e);
            } finally {
                executorService.shutdown();
            }
        }
    }
}

Future介绍
https://blog.csdn.net/daohangtaiqian/article/details/129611894?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168661259316782425174780%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=168661259316782425174780&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_click~default-2-129611894-null-null.142v88control_2,239v2insert_chatgpt&utm_term=Future&spm=1018.2226.3001.4187

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值