自学内容网 自学内容网

31.Java Callable 接口与 FutureTask 类

一、Callable 接口

1、概述
  • 目前我们学习了有两种创建线程的方法,一种是通过继承 Thread 类,另一种是
    通过实现 Runnable 接口创建线程,但是,Runnable 缺少的一项功能是,当线程
    终止时(即 run 方法完成时),无法使线程返回结果,为了支持此功能,Java 中提供了 Callable 接口
2、Callable 接口对比 Runnable 接口
  • 实现 Runnable 接口,需要实现无返回值的 run 方法,实现 Callable 接口,需要实现在有返回值的 call 方法

  • run 方法不会抛出异常,call 方法会抛出异常

3、实现 Runnable 接口和 Callable 接口
class MyThread1 implements Runnable {
    @Override
    public void run() {
        System.out.println("实现 Runnable 接口");
    }
}

class MyThread2 implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println("实现 Callable 接口");
        return 100;
    }
}
4、Callable 实现线程创建问题
  • Thread 类的构造器不支持接收 Callable 实现

  • 需要寻找一个类,既和 Runnable 接口有关,又和 Callable 接口有关

  • FutureTask 类满足条件,该类实现了 Runnable 接口,构造器支持接收 Callable 实现


二、FutureTask 类

1、构造器
  • 创建一个 FutureTask 对象,一旦运行就执行 Callable 实现
public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;
}
  • 创建一个 FutureTask 对象,一旦运行就执行 Runnable 实现,并安排成功完成时 get 方法返回给定的 result
public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;
}
2、常用方法
方法说明
get()获取结果
boolean isDone()判断是否执行完毕
3、基本使用
package com.my.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        // Runnable
        Thread thread1 = new Thread(new MyThread1(), "AA");

        // Callable
        FutureTask futureTask1 = new FutureTask(new MyThread2());
        FutureTask<Integer> futureTask2 = new FutureTask(() -> {
            System.out.println(Thread.currentThread().getName() + " 实现了 Callable 接口");
            return 200;
        });
        FutureTask<Integer> futureTask3 = new FutureTask<Integer>(new MyThread1(), 300);

        Thread thread2 = new Thread(futureTask1, "BB");
        Thread thread3 = new Thread(futureTask2, "CC");
        Thread thread4 = new Thread(futureTask3, "DD");

        // 开启线程
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

        Thread.sleep(1000);

        // isDone 方法
        System.out.println(futureTask1.isDone());
        System.out.println(futureTask2.isDone());
        System.out.println(futureTask3.isDone());

        // get 方法
        System.out.println(futureTask1.get());
        System.out.println(futureTask2.get());
        System.out.println(futureTask3.get());
    }
}

class MyThread1 implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 实现了 Runnable 接口");
    }
}

class MyThread2 implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName() + " 实现了 Callable 接口");
        return 100;
    }
}

原文地址:https://blog.csdn.net/weixin_52173250/article/details/145216517

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!