Java 的 Runnable、Callable、Executor 和 Future 的关系和使用例子

  1. Runnable、Callable、Executor 和 Future 的关系
  2. Runnable、Callable、Executor 和 Future 的使用例子

学了 Java 的多线程这几个接口后呢,可能还很多人傻傻分不清楚这几个接口之间到底是什么关系,有什么区别,分别有什么作用,本文简单介绍一下

RunnableCallableExecutorFuture 的关系

  1. Runnable 接口:是 Java 中的一个标准接口,用于描述一个可运行的任务。通过实现 Runnable 接口并重写 run 方法,可以定义一个线程要执行的任务内容,本身不支持返回值或抛出受检异常。

  2. Callable 接口:与 Runnable 接口类似,也是一个标准接口,但是它可以返回一个值或者抛出一个异常。通过实现 Callable 接口并重写 call 方法,可以定义一个线程要执行的任务内容,并返回一个结果。

  3. Executor 接口:是一个线程池管理接口,定义了线程池的执行方式和行为。通过实现 Executor 接口并重写 execute 方法,可以自定义线程池的执行策略。可以通过 Executors 中的静态工厂方法之一来创建线程池。

  4. Future 接口:表示一个异步计算的结果,可以通过 get 方法获取计算结果。Future 接口可以用于在任务执行完成之前,先返回一个 Future 对象,然后在需要结果时再通过 get 方法获取结果。

RunnableCallableExecutorFuture 的使用例子

  1. 使用 RunnableExecutor实现一个打印 10 个数的任务

     public class Main {
         public static void main(String[] args) throws ExecutionException, InterruptedException {
             ExecutorService service = Executors.newSingleThreadExecutor(); // ExecutorService 接口扩展了 Executor 接口
             Runnable r = () -> {
                 for (int i = 1; i <= 10; i++) {
                     System.out.println(i);
                 }
             };
             service.execute(r);
             service.shutdown(); // 关闭 ExecutorService,释放线程池资源
         }
     }
    
  2. 使用 CallableExecutor 实现一个求 1 到 10 的和的任务,并输出结果

    public class Main {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            ExecutorService service = Executors.newSingleThreadExecutor(); // ExecutorService 接口扩展了 Executor 接口
            Callable task = () -> {
                int sum = 0;
                for (int i = 1; i <= 10; i++)
                    sum += i;
                return sum;
            };
            Future<Integer> future = service.submit(task);
            System.out.println("1 + 2 + ... + 10 = " + future.get());
            service.shutdown(); // 关闭 ExecutorService,释放线程池资源
        }
    }
    
  3. 使用 ExecutorFuture 处理一批任务

    public class Main {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            ExecutorService executor = Executors.newFixedThreadPool(5);
            // 创建一批 Callable 任务
            List<Callable<Integer>> taskList = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                int finalI = i;
                Callable<Integer> task = () -> {
                    Thread.sleep(1000); // 模拟任务执行需要 1 秒钟
                    return finalI;
                };
                taskList.add(task);
            }
    
            // 提交一批任务给 ExecutorService 并获取一个 Future 列表
            List<Future<Integer>> futures = executor.invokeAll(taskList);
            // 遍历 Future 列表,并在每个 Future 对象上调用 get 方法以获取任务执行结果
            for (Future<Integer> future : futures) {
                System.out.println("Task_" + future.get() + ": " + future.get());
            }
    
            executor.shutdown(); // 关闭 ExecutorService,释放线程池资源
        }
    }
    

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。