返回顶部
首页 > 资讯 > 精选 >Java中Future和FutureTask怎么用
  • 814
分享到

Java中Future和FutureTask怎么用

2023-06-21 21:06:25 814人浏览 泡泡鱼
摘要

小编给大家分享一下Java中Future和FutureTask怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、Future 接口当 call()方法完成时,结果必须存储在主线程已知的对象中,以便主线程可以知道该线程

小编给大家分享一下Java中Future和FutureTask怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

一、Future 接口

当 call()方法完成时,结果必须存储在主线程已知的对象中,以便主线程可以知道该线程返回的结果。为此,可以使用 Future 对象。

将 Future 视为保存结果的对象–它可能暂时不保存结果,但将来会保存(一旦Callable 返回)。Future 基本上是主线程可以跟踪进度以及其他线程的结果的一种方式。要实现此接口,必须重写 5 种方法,这里列出了重要的方法,如下:

public boolean isDone()

Java中Future和FutureTask怎么用

public boolean cancel(boolean mayInterruptIfRunning)

用于停止任务。如果尚未启动,它将停止任务。如果已启动,则仅在 mayInterrupt 为 true时才会中断任务。

Java中Future和FutureTask怎么用

boolean isCancelled()

如果任务在正常结束之前被取消返回true

public V get() throws InterruptedException, ExecutionException

用于获取任务的结果。如果任务完成,它将立即返回结果,否则将等待任务完成,然后返回结果。

public V get(long timeout, TimeUnit unit)    throws InterruptedException, ExecutionException, TimeoutException

如果任务完成,则返回 true,否则返回 false。

Callable 与 Runnable 类似,因为它封装了要在另一个线程上运行的任务,而 Future 用于存储从另一个线程获得的结果

实际上,Future 也可以与 Runnable 一起使用。要创建线程,需要 Runnable。为了获得结果,需要 future。

二、FutureTask

介绍:当一个线程需要等待另一个线程把某个任务执行完后它才能继续执行,此时可以使用FutureTask。假设有多个线程执行若干任务,每个任务最多只能被执行一次。当多个线程试图同时执行同一个任务时,只允许一个线程执行任务,其他线程需要等待这个任务执行完后才能继续执行。

Java 库具有具体的 FutureTask 类型,该类型实现 Runnable 和 Future,并方便地将两种功能组合在一起。 可以通过为其构造函数提供 Callable 来创建FutureTask。然后,将 FutureTask 对象提供给 Thread 的构造函数以创建Thread 对象因此,间接地使用 Callable 创建线程

FutureTask状态转换

FutureTask有以下7种状态:

FutureTask任务的运行状态,最初为NEW。运行状态仅在set、setException和cancel方法中转换为终端状态。在完成过程中,状态可能呈现出瞬时值INTERRUPTING(仅在中断运行程序以满足**cancel(true)**的情况下)或者COMPLETING(在设置结果时)状态时。从这些中间状态到最终状态的转换使用成本更低的有序/延迟写,因为值是统一的,需要进一步修改。

state:表示当前任务的运行状态,FutureTask的所有方法都是围绕state开展的,state声明为volatile,保证了state的可见性,当对state进行修改时所有的线程都会看到

NEW:表示一个新的任务,初始状态

COMPLETING:当任务被设置结果时,处于COMPLETING状态,这是一个中间状态。

NORMAL:表示任务正常结束。

EXCEPTIONAL:表示任务因异常而结束

CANCELLED:任务还未执行之前就调用了cancel(true)方法,任务处于CANCELLED

INTERRUPTING:当任务调用cancel(true)中断程序时,任务处于INTERRUPTING状态,这是一个中间状态。

INTERRUPTED:任务调用cancel(true)中断程序时会调用interrupt()方法中断线程运行,任务状态由INTERRUPTING转变为INTERRUPTED

可能的状态过渡:
1、NEW -> COMPLETING -> NORMAL:正常结束
2、NEW -> COMPLETING -> EXCEPTIONAL:异常结束
3、NEW -> CANCELLED:任务被取消
4、NEW -> INTERRUPTING -> INTERRUPTED:任务出现中断

三、使用 Callable 和 Future

Runnable缺少的一项功能是,当线程终止时(即 run()完成时),我们无法使线程返回结果。

为了支持此功能,Java 中提供了 Callable 接口。不能直接替换 runnable,因为 Thread 类的构造方法根本没有 Callable。

所以我们可以找一个中间人,也就是FutureTask。

Java中Future和FutureTask怎么用

Java中Future和FutureTask怎么用

案例

class MyThreadA implements Callable {    @Override    public Object call() throws Exception {        System.out.println(Thread.currentThread().getName() + "在call方法里");        System.out.println(Thread.currentThread().getName() + "线程进入了 call方法,开始睡觉(进行了一些计算)");        Thread.sleep(10000);        System.out.println(Thread.currentThread().getName() + "睡醒了");        return Thread.currentThread().getName() + "返回的:" + System.currentTimeMillis();    }}public class demo1 {    public static void main(String[] args) throws ExecutionException, InterruptedException {        FutureTask<Integer> futureTaskA = new FutureTask<>(new MyThreadA());        FutureTask<String> futureTaskB = new FutureTask<>(()->{            System.out.println(Thread.currentThread().getName() + "在call方法里");            return Thread.currentThread().getName() + "返回的:" + System.currentTimeMillis();        });        new Thread(futureTaskA,"线程A").start();        new Thread(futureTaskB,"线程B").start();        while (!futureTaskB.isDone()){  //isDone表示FutureTask的计算是否完成            System.out.println("wait.......");        }        System.out.println(futureTaskA.get());        System.out.println(futureTaskB.get());        System.out.println(Thread.currentThread().getName() + "结束了");    }}

输出结果:

Java中Future和FutureTask怎么用

由上图两个线程返回的时间差约等于10秒可以看出,当一个线程(线程B)需要等待(一直wait…)另一个线程(线程A)把某个任务(进行了一些计算)执行完后它才能继续执行,此时可以使用FutureTask。不管futureTaskA.get()和futureTaskB.get()谁在前面,输出结果一定是“线程B返回的:xxx”在“wait…”的后面。假设有多个线程执行若干任务,每个任务最多只能被执行一次。当多个线程试图同时执行同一个任务时,只允许一个线程执行任务,其他线程需要等待这个任务执行完后才能继续执行。

四、小结(FutureTask核心原理)

FutureTask核心原理

在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给 Future 对象在后台完成,当主线程将来需要时,就可以通过 Future对象获得后台作业的计算结果或者执行状态。

• 一般 FutureTask 多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果

• 仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。get 方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常。

• get只计算一次,因此 get 方法放到最后

附:FutureTask在高并发环境下确保任务只执行一次

网上有篇例子,但是中间讲的不是很清楚。我重新梳理了一下。

在很多高并发的环境下,往往我们只需要某些任务只执行一次。这种使用情景FutureTask的特性恰能胜任。举一个例子,假设有一个带key的连接池,当key存在时,即直接返回key对应的对象;当key不存在时,则创建连接。对于这样的应用场景,通常采用的方法为使用一个Map对象来存储key和连接池对应的对应关系,典型的代码如下面所示:

package com.concurrency.chapter15;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.HashMap;import java.util.Map;import java.util.concurrent.locks.ReentrantLock;public class FutureTaskConnection1 {    private static Map<String, Connection> connectionPool = new HashMap<>();    private static ReentrantLock lock = new ReentrantLock();    public static Connection getConnection(String key) {        try {            lock.lock();            Connection connection = connectionPool.get(key);            if (connection == null) {                Connection newConnection = createConnection();                connectionPool.put(key, newConnection);                return newConnection;            }            return connection;        } finally {            lock.unlock();        }    }    private static Connection createConnection() {        try {            return DriverManager.getConnection("");        } catch (SQLException e) {            e.printStackTrace();        }        return null;    }}

看完了这篇文章,相信你对“Java中Future和FutureTask怎么用”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网精选频道,感谢各位的阅读!

--结束END--

本文标题: Java中Future和FutureTask怎么用

本文链接: https://lsjlt.com/news/300907.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java中Future和FutureTask怎么用
    小编给大家分享一下Java中Future和FutureTask怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、Future 接口当 call()方法完成时,结果必须存储在主线程已知的对象中,以便主线程可以知道该线程...
    99+
    2023-06-21
  • Java多线程 Callable、Future 和FutureTask
    目录1 Callable介绍2 Future介绍2.1 在Future接口中声明方法2.2 Future提供了三种功能3 FutureTask4 Future和FutureTask的...
    99+
    2024-04-02
  • Java中Future和FutureTask的示例详解及使用
    目录一、Future 接口二、FutureTask三、使用 Callable 和 Future四、小结(FutureTask核心原理)总结一、Future 接口 当 call()方法...
    99+
    2024-04-02
  • Java多线程中Callable、Future和FutureTask是什么意思
    小编给大家分享一下Java多线程中Callable、Future和FutureTask是什么意思,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言:创建线程的2种...
    99+
    2023-06-25
  • Future怎么在java中使用
    Future怎么在java中使用?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了...
    99+
    2023-06-14
  • java多线程编程同步器Future和FutureTask解析及代码示例
    publicinterfaceFuture<V>Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用get方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消...
    99+
    2023-05-30
    java 多线程 ava
  • Future怎么在Java与Scala中使用
    Future怎么在Java与Scala中使用?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Future很多同学可能会有疑问,Futrue跟异步编程有什么关系?从...
    99+
    2023-05-30
    java scala future
  • Future和Callable怎么使用
    这篇“Future和Callable怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“...
    99+
    2024-04-02
  • Future和Promise怎么在Golang中使用
    这篇文章给大家介绍Future和Promise怎么在Golang中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一个Future就是说“将来”你需要某些东西(一般就是一个网络请求的结果),但是你现在就要发起这样的请...
    99+
    2023-06-14
  • java中怎么利用FutureTask实现异常编程
    这期内容当中小编将会给大家带来有关java中怎么利用FutureTask实现异常编程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。说明FutureTask类不仅实现了Future接口还实现了Runnabl...
    99+
    2023-06-20
  • Java多线程中Future设计模式怎么用
    这篇文章将为大家详细讲解有关Java多线程中Future设计模式怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Future -> 代表的是未来的一个凭据public interfac...
    99+
    2023-06-25
  • Java中如何使用Callable和Future接口详解
    本篇文章给大家分享的是有关Java中如何使用Callable和Future接口详解,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Runnable是一个接口,而Thread是Ru...
    99+
    2023-06-20
  • Java中的Future机制作用是什么
    这篇文章主要介绍“Java中的Future机制作用是什么”,在日常操作中,相信很多人在Java中的Future机制作用是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中的Future机制作用是什么...
    99+
    2023-06-20
  • 怎么在java中利用Future获取线程结果
    怎么在java中利用Future获取线程结果?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整数的数据...
    99+
    2023-06-14
  • Java的Future多线程模式怎么使用
    本篇内容介绍了“Java的Future多线程模式怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在Java5后,提供了大量处理多线程的...
    99+
    2023-06-17
  • 如何在Java中使用FutureTask实现多线程
    如何在Java中使用FutureTask实现多线程?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、FutureTask的理解FutureTask属于java.util.con...
    99+
    2023-06-15
  • Java中多线程对运行结果怎么利用future获取
    Java中多线程对运行结果怎么利用future获取?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Future接口是Java标准API的一部分,在java.util.conc...
    99+
    2023-05-31
    java 多线程 future
  • 浅析Java中Future接口的使用方法
    目录引言一、Future接口简介二、Future接口的原理三、Future接口的核心方法解析四、Future接口的实现类五、Future接口的源码解读六、Future接口的使用示例结...
    99+
    2023-05-19
    Java Future接口使用方法 Java Future接口使用 Java Future接口
  • 怎么使用Java多线程Future获取异步任务
    本篇内容主要讲解“怎么使用Java多线程Future获取异步任务”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Java多线程Future获取异步任务”吧!Runnable的局限性在前文中...
    99+
    2023-07-05
  • Java多线程中怎么利用Future实现携带结果的任务
    本篇文章为大家展示了Java多线程中怎么利用Future实现携带结果的任务,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Future 介绍Future表示异步计算的结果,它提供了检查计算是否完成的方...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作