并发编程原理与实战(三)一步步剖析线程返回值

并发编程原理与实战(一)精准理解线程的创建和停止

并发编程原理与实战(二)Thread类关键API详解

通过前面两篇文章,我们已经掌握了创建线程、运行、停止相关方法了,接下来我们继续学习线程的返回值,这样线程创建、运行、返回、终止的整个过程算是有个闭环了。

Runnable接口

Runnable接口是并发编程的核心接口之一,作用是‌定义线程执行的任务,将任务逻辑与线程的执行机制解耦。

@FunctionalInterface
public interface Runnable {
   
   
    /**
     * Runs this operation.
     */
    void run();
}

接口中只有一个run()方法,该方法没有返回值,其设计同样遵循单一职责原则,实现了该接口表明具备运行线程任务的能力,Thread类同样实现了该接口。看下面一个简单的例子。

public class ThreadTask implements Runnable{
   
   
    @Override
    public void run() {
   
   
        System.out.println(Thread.currentThread().getName()+" run");
    }
    public static void main(String[] args) {
   
   
        Thread t = new Thread(new ThreadTask());
        t.start();
    }
}

上面的例子,线程t启动运行完后就完了,但是如果想要线程t运行完后返回一个变量,那该如何实现?

Callable接口

在jdk1.5之后,引入Callable接口来解决线程返回值的问题。

/**
 * A task that returns a result and may throw an exception.
 * Implementors define a single method with no arguments called
 * {@code call}.
 *
 * <p>The {@code Callable} interface is similar to {@link
 * java.lang.Runnable}, in that both are designed for classes whose
 * instances are potentially executed by another thread.  A
 * {@code Runnable}, however, does not return a result and cannot
 * throw a checked exception.
 *
 * <p>The {@link Executors} class contains utility methods to
 * convert from other common forms to {@code Callable} classes.
 *
 * @see Executor
 * @since 1.5
 * @author Doug Lea
 * @param <V> the result type of method {@code call}
 */
@FunctionalInterface
public interface Callable<V> {
   
   
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

从注释中可以看出,Callable接口类似Runnable接口,同样是用来定义线程执行的任务,也是只有一个方法,但是Callable接口比Runnable接口多了两个功能,就是可以返回任意类型的返回值和可以抛出异常。需要注意的是Callable类型的任务对象并不能像Runnable类型的任务对象一样用,直接传入Thread类的构造函数创建线程,从前面的文章中我们得知Thread类的构造函数并没有Callable类型的参数。那Callable怎么用?线程返回结果用什么表示?我们接着往下看。

Future接口

Thread类只接收Runnable类型的任务但是没有返回值,Callable类型的任务有返回值但是不能往Thread类里面传。这不就是牛郎和织女隔着一条银河想相爱又不能靠近吗,给他们搭一座桥满足他们吧。面向对象程序设计就是这么人性化,总能在生活中找比喻的例子。Future与FutureTask的引入就是为了解决这一问题。Future接口也是在jdk1.5之后引入的,源码如下:

/**
 * A {@code Future} represents the result of an asynchronous
 * computation.  Methods are provided to check if the computation is
 * complete, to wait for its completion, and to retrieve the result of
 * the computation.  The result can only be retrieved using method
 * {@code get} when the computation has completed, blocking if
 * necessary until it is ready.  Cancellation is performed by the
 * {@code cancel} method.  Additional methods are provided to
 * determine if the task completed normally or was cancelled. Once a
 * computation has completed, the computation cannot be cancelled.
 * If you would like to use a {@code Future} for the sake
 * of cancellability but not provide a usable result, you can
 * declare types of the form {@code Future<?>} and
 * return {@code null} as a result of the underlying task.
 ...
 *
 * @see FutureTask
 * @see Executor
 * @since 1.5
 * @author Doug Lea
 * @param <V> The result type returned by this Future's {@code get} method
 */
public interface Future<V> {
   
   
    ...
}

Future接口表示一个异步计算任务的返回结果,提供了检查任务是否完成、等待任务完成直到返回结果、取消任务执行、获取任务状态等方法。下面我们来学习下Future接口的属性和方法。

在这里插入图片描述

1、get()方法

/**
 * Waits if necessary for the computation to complete, and then
 * retrieves its result.
 *
 * @return the computed result
 * @throws CancellationException if the computation was cancelled
 * @throws ExecutionException if the computation threw an
 * exception
 * @throws InterruptedException if the current thread was interrupted
 * while waiting
 */
V get() throws InterruptedException, ExecutionException;

调用get()方法将等待任务完成并返回结果,如果在等待任务完成的过程中任务被取消了将会抛出取消异常,如果任务执行过程出现异常将会抛出执行异常,如果在等待任务完成的过程中线程被中断,将会抛出中断异常。V get(long timeout, TimeUnit unit)方法可以指定等待指定时间,等待超时了还没有返回则抛出超时异常。

2、boolean cancel(boolean mayInterruptIfRunning)方法

    /**
     * Attempts to cancel execution of this task.  This method has no
     * effect if the task is already completed or cancelled, or could
     * not be cancelled for some other reason.  Otherwise, if this
     * task has not started when {@code cancel} is called, this task
     * should never run.  If the task has already started, then the
     * {@code mayInterruptIfRunning} parameter determines whether the
     * thread executing this task (when known by the implementation)
     * is interrupted in an attempt to stop the task.
     *
     * <p>The return value from this method does not necessarily
     * indicate whether the task is now cancelled; use {@link
     * #isCancelled}.
     *
     * @param mayInterruptIfRunning {@code true} if the thread
     * executing this task should be interrupted (if the thread is
     * known to the implementation); otherwise, in-progress tasks are
     * allowed to complete
     * @return {@code false} if the task could not be cancelled,
     * typically because it has already completed; {@code true}
     * otherwise. If two or more threads cause a task to be cancelled,
     * then at least one of them returns {@code true}. Implementations
     * may provide stronger guarantees.
     */
    boolean cancel(boolean mayInterruptIfRunning);

调用该方法将试图去取消正在执行的任务,需要注意的是,如果任务还没有启动就调用该方法,那么任务将不会执行。如果任务已经启动了,传入的参数mayInterruptIfRunning将决定正在执行的线程是否可以被中断以便停止任务。

传入的mayInterruptIfRunning的值为true时,正在运行中的线程将被中断(如果已知线程已经执行完成),否则传入false时,进行中的任务应当允许完成。

如果任务不可以被取消那么将返回false,否则返回true。如果有多个线程同时取消了任务,那么至少有一个线程返回true。

综合上述,调用该方法只是试图去取消任务,并不能确定任务现在是已经被取消了,需要通过调用isCancelled()方法来判断,如果任务在正常的完成之前被取消了,那么该方法将返回true。

3、isDone()方法

    /**
     * Returns {@code true} if this task completed.
     *
     * Completion may be due to normal termination, an exception, or
     * cancellation -- in all of these cases, this method will return
     * {@code true}.
     *
     * @return {@code true} if this task completed
     */
    boolean isDone();

判断任务是否已经完成。

4、resultNow()方法

/**
     * Returns the computed result, without waiting.
     *
     * <p> This method is for ca
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帧栈

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值