JAVA JUC Callable 接口

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
应用实时监控服务ARMS - 应用监控,每月50GB免费额度
云原生网关 MSE Higress,422元/月
简介: 【1月更文挑战第5天】JAVA JUC Callable 接口

Callable 接口:

创建线程的多种方式:

  1. 继承Thread类
  2. 实现Runnable接口
  3. Callable接口
  4. 线程池

1.Callable接口创建线程:

目前学习了有两种创建线程的方法,一种是通过创建 Thread 类,另一种是通过使用 Runnable 创建线程,但是,Runnable 缺少的一项功能是,当线程终止时(即 run()完成时),我们无法使线程返回结果。为了支持此功能,Java 中提供了 Callable 接口:

比较Runnable接口和Callable接口:

  • Callable中的call()计算结果,如果无法计算结果,会抛出异常。
  • Runnable中的run()使用实现接口Runnable的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用该对象的run方法。

总的来说:run()没有返回值,不会抛出异常。而call()有返回值,会抛出异常

2.FutureTask 实现类:

因为Thread的构造函数中没有Callable接口的参数设置,直接替换不可以,只能用下面这种线程创建方法(找一个类,即和Runnable接口有关系,又和Callable接口有关系)

发现Runnable接口有实现类FutureTask(中间对象)未来任务

FutureTask的构造函数有Callable参数,通过FutureTask创建线程对象,java.util.concurrent.FutureTask<V>

https://www.matools.com/file/manual/jdk_api_1.8_google/java/util/concurrent/FutureTask.html

使用 lambda 方式创建代码如下:

public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+"执行Runnable");
        }).start();
        FutureTask<String> task = new FutureTask<>(() -> {
            System.out.println(Thread.currentThread().getName() + "使用Callable接口");
            return "Callable接口返回值";
        });
        new Thread(task).start();
        System.out.println("Callable返回值:" + task.get());
    }
}


//比较 callable和runnable 的区别
class MyThread1 implements Runnable{
    @Override
    public void run() {
        //这里没有返回值
    }
}
class MyThread2 implements Callable{
    @Override
    public Object call() throws Exception {
        System.out.println(Thread.currentThread().getName()+"线程运行");
        return "Callable 的实现线程";  //有返回值
    }
}
public class diffentence {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建 实现Runnable 的线程
        new Thread( new MyThread1(),"t1" ).start();
        //创建 实现Callable 的线程 不能直接替换 ,没有这个类型的构造方法
        // new Thread( new MyThread2(),"t2" ).start();
        //选择FutureTask 他是 Runnable 的实现类,而且构造方法含有Callable类型
        FutureTask<String>  task = new FutureTask(new MyThread2());
        new Thread(task,"hhh").start();
        System.out.println("返回值"+task.get()); //调用里面的返回值
    }
}

源码解析:

进入FutureTask底层源码可以看到它的构造器:

// 创建一个FutureTask,一旦运行就执行给定的Callable
public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;       // ensure visibility of callable
}
// 创建一个FutureTask,一旦运行就执行给定的Ru你那边了,并安排成功完成时get返回给定的结果
public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;       // ensure visibility of callable
}

其他常用的代码:

// get()获取call方法计算完成的返回值结果:
public V get() throws InterruptedException, ExecutionException {
    int s = state;
    if (s <= COMPLETING)
        s = awaitDone(false, 0L);
    return report(s);
}
// outcome就是返回值:
private V report(int s) throws ExecutionException {
    Object x = outcome;
    if (s == NORMAL)
        return (V)x;
    if (s >= CANCELLED)
        throw new CancellationException();
    throw new ExecutionException((Throwable)x);
}

未来的任务,如果运行过一次,那么下一次,就直接得到结果!

相关文章
|
1天前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
13 6
|
1天前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
【10月更文挑战第16天】Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。通过 hashCode() 和 equals() 方法实现唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 添加和遍历元素,体现了 Set 的高效性和简洁性。
11 4
|
3天前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。它通过 hashCode() 和 equals() 方法确保元素唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 实现这一特性。
11 5
|
1天前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
7 2
|
3天前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其独特的“不重复性”要求,彻底改变了处理唯一性约束数据的方式。
【10月更文挑战第14天】从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其独特的“不重复性”要求,彻底改变了处理唯一性约束数据的方式。本文深入探讨Set的核心理念,并通过示例代码展示了HashSet和TreeSet的特点和应用场景。
8 2
|
5月前
|
存储 Java
高并发编程之多线程锁和Callable&Future 接口
高并发编程之多线程锁和Callable&Future 接口
74 1
|
2月前
|
并行计算 Java 大数据
Callable和Future
Callable和Future
|
5月前
|
Java
Java并发编程:理解并使用Future和Callable接口
【2月更文挑战第25天】 在Java中,多线程编程是一个重要的概念,它允许我们同时执行多个任务。然而,有时候我们需要等待一个或多个线程完成,然后才能继续执行其他任务。这就需要使用到Future和Callable接口。本文将深入探讨这两个接口的用法,以及它们如何帮助我们更好地管理多线程。
|
11月前
|
Java
ExecutorService、Callable、Future实现有返回结果的多线程原理解析
ExecutorService、Callable、Future实现有返回结果的多线程原理解析
68 0
|
11月前
|
存储 Java
并发编程系列教程(09) - Callable与Future模式
并发编程系列教程(09) - Callable与Future模式
50 0