Java中的并发(二)

本文主要介绍Runnable、Callable、Executor、Future等接口以及他们的关系



并发相关接口图

并发相关接口关系图

这篇文章中介绍了通过Runnable、Thread来创建线程,下面介绍上图中其他相关的接口

Runnable

java.lang.Runnable接口表示一个可以运行的单位, 它只有一个方法:void run(), Theard类是它的子类。
由于run()方法返回值为void类型,所以Runnable在执行完任务之后无法返回任何结果。

Callable

Java1.5 出现了java.util.concurrent.Callable接口也可以表示一个可运行的单元, 它有一个V call()方法, 可以返回执行的结果.
Runnable可以交给一个Thread直接启动一个线程, Callable一般需要交给ExecuteService来执行.

Executor

java.util.concurrent.ExecutorJava1.5出现的执行器, 角色类似于调度着, 跟它相关的内容包括线程池, Executor, Executors, ExecutorService, CompletionService, Future, Callable等, 它的引入大大简化了并发编程.
它有一个void execute(Runnable command)方法可以调度执行Runnable.

ExecutorService

ExecutorServiceExecutor最常用的子接口, 可以当成是RunnableCallable的调度容器, 它重载了几个submit方法:

  • <T> Future<T> submit(Callable<T> task): 提交一个有返回结果的任务(Callable)
  • <T> Future<T> submit(Runnable task, T result): 提交一个Runnable, 正确执行完成的结果将会是result
  • Future<?> submit(Runnable task):提交一个没有返回结果的任务(Runnable)

还有其他方法, 暂不细说

Future

java.util.concurrent.Future是任务执行结果的查看着, 里面有方法比较简单

  • boolean cancel(boolean mayInterruptIfRunning): 取消任务, 取消成功返回true, 取消失败返回false. 参数mayInterruptIfRunning仅表示是否允许取消正在执行却没有执行完毕的任务, 若任务还没执行, 则会取消该任务并返回true; 若任务已经执行完成, 则相当于取消失败, 直接返回false; 若任务执行中, 还没执行完, 这个参数就要起作用了, 传true则取消该正在执行的任务, 返回true表示取消成功.
  • boolean isCancelled(): 任务是否被取消成功, 如果任务正常完成前被取消成功, 则返回true
  • boolean isDone(): 任务是否已经完成, 若任务完成, 则返回true
  • V get(): 获取执行结果, 这个方法会产生阻塞, 会一直等到任务执行完毕才返回(这个方法比较常用)
  • V get(long timeout, TimeUnit unit): 获取执行结果, 如果在指定时间内, 还没获取到结果, 就直接返回null

总结及示例

  • RunnableCallable是可执行的单位(一个无返回值, 一个有返回值)
  • ExecutorService可以提交一个可执行单位
  • Future是用来存放调度完成返回的结果的,可通过get()方法获取执行结果

下面是一个例子:

public class ConcurrentTest {
    public static void main(String[] args) {
        // 创建一个执行器
        ExecutorService executor = Executors.newFixedThreadPool(3);
        // 1.Runnable通过Future返回结果为空
        Future<?> future1 = executor.submit(new Runnable() {
            public void run() {
                System.out.println("runnable running.");
            }
        });
        // 2.Callable通过Future能返回结果
        Future<String> future2 = executor.submit(new Callable<String>() {
            public String call() throws Exception {
                System.out.println("callable running.");
                return "CallableResult";
            }
        });
        // 获得任务的结果
        try {
            System.out.println("Runnable return:" + future1.get());  // Runnable return:null
            System.out.println("Callable return:" + future2.get()); // Callable return:CallableResult
        } catch (Exception e) {
            System.out.println("get会抛出InterruptedException, ExecutionException异常");
        }
        executor.shutdown();
    }
}