Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Runnable和Callable源码及应用解析

Runnable和Callable源码及应用解析

作者头像
余生大大
发布于 2022-11-02 06:55:37
发布于 2022-11-02 06:55:37
20000
代码可运行
举报
文章被收录于专栏:余生大大余生大大
运行总次数:0
代码可运行

1、Runnable源码解析

看一下Runnable的源码,很简单

他的内容这么少是怎么实现我们繁杂的需求和应用呢?

使用Runnable创建一个线程解析一下代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public static void main(String[] args) {
        new Thread(()->{
            System.out.println("我是Runnable");
        }).start();
    }

里面使用Runnable的地方只有传递对象的时候,其他都是使用的Thread而Thread又实现了我们的Runnable,所以Runbale可以理解为执行代码的对象,执行的过程和线程的操作交由Thread控制,Thread源码可以看 ----》Thread源码解析

2、Callable源码解析

Callable的源码,跟Runnable不同的是它不能直接由Thread进行应用启动,还需要一个类Future

Future源码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface Future<V> {

    /**
     cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
     */
    boolean cancel(boolean mayInterruptIfRunning);

    /**
     isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
     */
    boolean isCancelled();

    /**
     isDone方法表示任务是否已经完成,若任务完成,则返回true;
     */
    boolean isDone();

    /**
     get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
     */
    V get() throws InterruptedException, ExecutionException;

    /**
     get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

上面的源码可以看到,cancel可以取消任务,isCancelled、isDone可以验证任务是否被取消,get可以获取返回值,但是它是一个接口并不能直接使用,所以就有了它的实现类FutureTask。

看一下FutureTask源码又实现了谁

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class FutureTask<V> implements RunnableFuture<V> {

可以看到又出现了一个新的内容RunnableFuture,看一下它的内容。

FutureTask的构造函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

Callabel代码测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class ThreadCallabel implements Callable<String>{

    @Override
    public String call() throws Exception {
        System.out.println("到call了");
        return "余生大大";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 获得执行对象
        ThreadCallabel threadCallabel = new ThreadCallabel();
        // 放入对象
        FutureTask<String> futureTask = new FutureTask(threadCallabel);
        // Thread执行
        new Thread(futureTask).start();
        // 获取返回内容
        String result = futureTask.get();
        // 输入结果
        System.out.println(result);
    }
}

输出内容

还有一种执行方式是通过ExecutorService执行,代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class ThreadCallabel implements Callable<String>{

    @Override
    public String call() throws Exception {
        System.out.println("到call了");
        return "余生大大";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建ExecutorService
        ExecutorService executor = Executors.newCachedThreadPool();
        // 获取执行对象
        ThreadCallabel threadCallabel = new ThreadCallabel();
        // 放入执行对象
        FutureTask<String> futureTask = new FutureTask<String>(threadCallabel);
        // 执行
        executor.submit(futureTask);
        // 释放资源
        executor.shutdown();
        // 输出结果
        System.out.println(futureTask.get());
    }
}

执行结果一样

Thread、Runnable是java.lang包下的内容。

Callable、Future、FutrueTask、RunnableFutrue、Executors、ExecutorService都是JUC(java.util.concurrent)包下的内容。

Executors也是创建线程池的工具类。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Callable/Future 使用及原理分析,Future .get()为啥能等待呢?
Callable/Future 和 Thread 之类的线程构建最大的区别在于,能够很方便的获取线程执行完以后的结果。首先来看一个简单的例子
源码之路
2020/09/04
5K0
Callable/Future 使用及原理分析,Future .get()为啥能等待呢?
创建线程都有哪些方式?— Callable篇
相信大家回答这个问题没什么难度吧?通常问完创建方式,那么接下来就是问「1、2」跟「3」创建方式的不同了,只要说出「3」有返回值基本这个问题就过了,不管是出于好奇还是疑惑,我们今天来会会这个Callable。
niceyoo
2020/07/26
8010
Java中的Runnable、Callable、Future、FutureTask的区别
Java中存在Runnable、Callable、Future、FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别。
开发者技术前线
2020/11/23
4700
Java并发编程之Future和FutureTask
搞过Java或者客户端Android开发的都知道,创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。不过,这2种方式都有一个缺陷,就是在执行完任务之后无法获取执行结果。
xiangzhihong
2022/11/30
3690
多线程设计模式 - Future模式之JAVA原生实现
JDK内置的Future设计模式主要使用到了Callable接口和FutureTask类。
JAVA日知录
2019/12/02
4040
Java 还有第三种创建多线程的方式?
我们在多线程编程中最常用的两种方式:一种是直接继承Thread,另外一种就是实现Runnable接口。这两种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。
互扯程序
2019/06/19
4830
高并发之——两种异步模型与深度解析Future接口
本文有点长,但是满满的干货,以实际案例的形式分析了两种异步模型,并从源码角度深度解析Future接口和FutureTask类,希望大家踏下心来,打开你的IDE,跟着文章看源码,相信你一定收获不小!
冰河
2020/10/29
5290
多线程 | FutureTask 执行流程
在 Java 中可以用来创建线程的方式很多,比如由 Java 提供的 Thread、Runnable 等。本文章来介绍使用 FutureTask 创建线程,以及其流程。
码农UP2U
2022/04/28
3060
J.U.C源码实战:Future编码实战与优缺点
在现代并发编程中,Java 的 Future 接口提供了一种处理异步计算结果的机制。Future 是 Java 5 中引入的 java.util.concurrent 包的一部分,用于表示一个任务的未来结果。随着应用程序需求的复杂化和多线程编程的普及,理解和运用 Future 变得尤为重要。本篇文章将深入探讨 Java 中 Future 的概念、使用方法及其在实际编程中的应用场景。通过学习这篇文章,读者将能够掌握如何使用 Future 接口进行异步操作,提升程序的性能和响应速度。此外,我们还将介绍与 Future 相关的其他关键类和接口,如 Callable 和 ExecutorService,以帮助读者全面了解并发编程的相关知识。无论你是刚接触 Java 并发编程的新手,还是希望深入理解和优化异步任务处理的开发者,这篇文章都将为你提供有价值的指导和参考。让我们一同开启对 Java Future 的学习之旅,探索并发编程的奥秘。
怒放吧德德
2024/06/23
1980
Future && FutureTask
线程的创建方式中有两种,一种是实现Runnable接口,另一种是继承Thread,但是这两种方式都有个缺点,那就是在任务执行完成之后无法获取返回结果,于是就有了Callable接口,Future接口与FutureTask类的配和取得返回的结果。
大学里的混子
2019/03/13
5540
FutureTask源码分析
FutureTask:一个可取消的异步任务执行类,这个类提供了Future接口的基本实现,主要有以下功能:
haifeiWu
2018/09/11
4140
FutureTask源码分析
线程池续:你必须要知道的线程池submit()实现原理之FutureTask!
FutureTask思维导图.png 前言 上一篇内容写了Java中线程池的实现原理及源码分析,说好的是实实在在的大满足,想通过一篇文章让大家对线程池有个透彻的了解,但是文章写完总觉得还缺点什
一枝花算不算浪漫
2020/06/01
2.1K0
(十一) J.U.C-FutureTask
FutureTask是J.U.C中的类,是一个可删除的异步计算类。这个类提供了Future接口的的基本实现,使用相关方法启动和取消计算,查询计算是否完成,并检索计算结果。只有在计算完成时才能使用get方法检索结果;如果计算尚未完成,get方法将会阻塞。一旦计算完成,计算就不能重新启动或取消(除非使用runAndReset方法调用计算)。
用户1212940
2022/04/13
2130
(十一) J.U.C-FutureTask
并发编程系列之FutureTask源码学习笔记
在上一章节的学习中,我们知道了Future类的基本用法,知道了Future其实就是为了监控线程任务执行的,接着本博客继续学习FutureTask。然后什么是FutureTask类?
SmileNicky
2021/09/08
3050
Future FutrueTask Callable类源码说明以及原理使用
  JDK内置的Future主要使用到了Callable接口和FutureTask类。
小勇DW3
2018/08/30
5630
Callable与Future介绍
在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。我们一般只能采用共享变量或共享存储区以及线程通信的方式实现获得任务结果的目的。不过,Java中,也提供了使用Callable和Future来实现获取任务结果的操作。Callable用来执行任务,产生结果,而Future用来获得结果。
HLee
2021/10/13
1K0
Callable与Future介绍
FutureTask 核心源码解析
研究源码,一般我们都从整体以及实例先入手,再研究细节,不至于一开始就“深陷其中而"当局者迷".
用户7118337
2020/04/15
5350
刚研究完Callable和Future,各位随便问!!
在Java的多线程编程中,除了Thread类和Runnable接口外,不得不说的就是Callable接口Future接口了。使用继承Thread类或者实现Runnable接口的线程,无法返回最终的执行结果数据,只能等待线程执行完成。此时,如果想要获取线程执行后的返回结果,那么,Callable和Future就派上用场了。
冰河
2021/04/30
6810
【小家Java】Future与FutureTask的区别与联系
所谓异步调用其实就是实现一个可无需等待被调用函数的返回值而让操作继续运行的方法。在 Java 语言中,简单的讲就是另启一个线程来完成调用中的部分计算,使调用继续运行或返回,而不需要等待计算结果。但调用者仍需要取线程的计算结果。
YourBatman
2019/09/03
2.2K0
Java并发编程:如何创建线程?
在 Java 中创建线程的方式有两种:1)继承 Thread 类  2)实现 Runnable 接口 3)实现 FutureTask 接口 前两种方式创建的线程都无法获取线程的执行结果,而通过 FutureTask 方式实现的线程可以获取线程执行的结果。 一、继承Thread类 package com.chanshuyi.thread; public class ThreadDemo1 { public static void main(String[] args) { ne
陈树义
2018/04/13
7290
Java并发编程:如何创建线程?
相关推荐
Callable/Future 使用及原理分析,Future .get()为啥能等待呢?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验