Java并发教程之Callable和Future接口详解

刚把Thread 的知识理了一遍。

Runnable是一个接口,而Thread是Runnable的一个实现类。

所以也就有了之前创建线程的两种方法

  • 继承Thread
  • 实现Runnable

我们看一下新建线程的方法:

都是得传入一个Runnable对象(这句话很关键)

所以传入一个Runnble和Thread对象都行。

现在引入创建线程的第三种方法:Callable

为了实现 Runnable,需要实现不返回任何内容的 run()方法,而对于

Callable,需要实现在完成时返回结果的 call()方法。

• call()方法可以引发异常,而 run()则不能。

Callable最大的特点就是 它能返回数值,并抛出异常,而且它不是run()方法,而是call()方法。

但是Callable最大的问题就是不能丢人Thread类中直接创建,因为Thread只认识Runnable,所以我们必须找到Callable和Runnable之间的桥梁。

也就是找一个类,即和Runnable友关系,又和Callable有关系。

这个类就是FutureTask了。

  • Runnable接口有实现类FutureTask
  • FutureTask构造可以传递Callable

所以创建也给Callable可以这样

新类 MyThread2 实现 callable 接口
class MyThread2 implements Callable<Integer>{
@Override
public Integer call() throws Exception {
return 200;
}

1、新建一个callable对象

Callable callable = new MyThread2()

2、传入callable对象,并新建一个futuretask对象,

FutureTask futureTask2 = new FutureTask(callable)

也可以之间通过lam表达式(函数式接口)实现

3、新建一个线程,传入FutureTask对象

new Thread(futureTask2, “线程二”).start()

这就是基本步骤。

接下来可以来扩展地讲讲 futuretask的作用

Future对象

Future 接口

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

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

• public boolean cancel(boolean mayInterrupt):用于停止任务。

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

• public Object get()抛出 InterruptedException,ExecutionException:

用于获取任务的结果。

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

• public boolean isDone():如果任务完成,则返回 true,否则返回 false可以看到 Callable 和 Future 做两件事-Callable 与 Runnable 类似,因为它封装了要在另一个线程上运行的任务,而 Future 用于存储从另一个线程获得的结
果。实际上,future 也可以与 Runnable 一起使用。

要创建线程,需要 Runnable。为了获得结果,需要 future。

FutureTask

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

核心原理:(重点)

在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给 Future 对象在后台完成

• 当主线程将来需要时,就可以通过 Future 对象获得后台作业的计算结果或者执行状态

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

• 仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get 方法

• 一旦计算完成,就不能再重新开始或取消计算

• get 方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常

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

举个例子吧。

比如现在老师在上课,但是他渴了,他想买水,但是还得继续上课。

这时就可以单独开启一条线程,让班长去帮他买水。(开启单独一条线程,不影响主线程的运行)

get方法可以得到return的值

isDone()方法可以判断是否完成了。


第一次会计算,第二次(之前计算过的),就直接返回结果了。

总结

到此这篇关于Java并发教程之Callable和Future接口的文章就介绍到这了,更多相关Java并发Callable和Future接口内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java并发编程之Executor接口的使用

    一.Executor接口的理解 Executor属于java.util.concurrent包下: Executor是任务执行机制的核心接口: 二.Executor接口的类图结构 由类图结构可知: ThreadPoolExecutor 继承了AbstractExecutorService接口: AbstractExecutorService接口实现了ExecutorService接口: ExecutorService继承了Executor接口: 因此以下部分主要讲解ThreadPoolExecu

  • Java并发编程Callable与Future的应用实例代码

    本文主要探究的是java并发编程callable与future的使用,分享了相关实例代码,具体介绍如下. 我们都知道实现多线程有2种方式,一种是继承Thread,一种是实现Runnable,但这2种方式都有一个缺陷,在任务完成后无法获取返回结果.要想获得返回结果,就得使用Callable,Callable任务可以有返回值,但是没法直接从Callable任务里获取返回值:想要获取Callabel任务的返回值,需要用到Future.所以Callable任务和Future模式,通常结合起来使用. 试想

  • Java并发教程之Callable和Future接口详解

    刚把Thread 的知识理了一遍. Runnable是一个接口,而Thread是Runnable的一个实现类. 所以也就有了之前创建线程的两种方法 继承Thread 实现Runnable 我们看一下新建线程的方法: 都是得传入一个Runnable对象(这句话很关键) 所以传入一个Runnble和Thread对象都行. 现在引入创建线程的第三种方法:Callable 为了实现 Runnable,需要实现不返回任何内容的 run()方法,而对于 Callable,需要实现在完成时返回结果的 call

  • Java并发编程之Semaphore(信号量)详解及实例

    Java并发编程之Semaphore(信号量)详解及实例 概述 通常情况下,可能有多个线程同时访问数目很少的资源,如客户端建立了若干个线程同时访问同一数据库,这势必会造成服务端资源被耗尽的地步,那么怎样能够有效的来控制不可预知的接入量呢?及在同一时刻只能获得指定数目的数据库连接,在JDK1.5 java.util.concurrent 包中引入了Semaphore(信号量),信号量是在简单上锁的基础上实现的,相当于能令线程安全执行,并初始化为可用资源个数的计数器,通常用于限制可以访问某些资源(物

  • java并发学习之BlockingQueue实现生产者消费者详解

    1.介绍 阻塞队列 (BlockingQueue)是Java util.concurrent包下重要的数据结构,BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满:从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空.并发包下很多高级同步类的实现都是基于BlockingQueue实现的. JDK7提供了以下7个阻塞队列: ArrayBlockingQueue :由数组结构组成的有界阻塞队列. LinkedBloc

  • java 并发中的原子性与可视性实例详解

    java 并发中的原子性与可视性实例详解 并发其实是一种解耦合的策略,它帮助我们把做什么(目标)和什么时候做(时机)分开.这样做可以明显改进应用程序的吞吐量(获得更多的CPU调度时间)和结构(程序有多个部分在协同工作).做过java Web开发的人都知道,Java Web中的Servlet程序在Servlet容器的支持下采用单实例多线程的工作模式,Servlet容器为你处理了并发问题. 原子性 原子是世界上的最小单位,具有不可分割性.比如 a=0:(a非long和double类型) 这个操作是不

  • Java并发中的Fork/Join 框架机制详解

    什么是 Fork/Join 框架 Fork/Join 框架是一种在 JDk 7 引入的线程池,用于并行执行把一个大任务拆成多个小任务并行执行,最终汇总每个小任务结果得到大任务结果的特殊任务.通过其命名也很容易看出框架主要分为 Fork 和 Join 两个阶段,第一阶段 Fork 是把一个大任务拆分为多个子任务并行的执行,第二阶段 Join 是合并这些子任务的所有执行结果,最后得到大任务的结果. 这里不难发现其执行主要流程:首先判断一个任务是否足够小,如果任务足够小,则直接计算,否则,就拆分成几个

  • Android入门教程之ListView的具体使用详解

    目录 ListView 的简单用法 定制 ListView 的界面 提升 ListView 的运行效率 ListView 的点击事件 ListView 的简单用法 在布局中加入 ListView 控件还算简单,先为 ListView 指定一个 id,然后将宽度和高度都设置为 match_parent,这样 ListView 就占满了整个布局的空间 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&

  • Android入门教程之RecyclerView的具体使用详解

    目录 RecyclerView 的基本用法 横向滚动 RecyclerView 点击事件 RecyclerView 的基本用法 和我们之前学习的控件不一样,RecyclerView 属于新增控件,所以我们需要在项目的 build.gradle 中添加 RecyclerView 库的依赖,才能使用该控件 dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementa

  • Android入门教程之Fragment的具体使用详解

    目录 Fragment 的简单用法 动态加载 Fragment Fragment 实现返回栈 Fragment 和 Activity 之间的交互 Fragment 生命周期 Fragment 的简单用法 Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因此在平板上应用非常广泛 在一个 Activity 中添加两个 Fragment,并让两个 Fragment 平分 Activity 的空间,首先新建一个左侧 Fragment

  • java Callable与Future的详解及实例

    java  Callable与Future Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务. Callable的接口定义如下: public interface Callable<V> { V call() throws Exception; <span id="transmark"></s

  • java  Callable与Future的详解及实例

    java  Callable与Future Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务. Callable的接口定义如下: public interface Callable<V> { V call() throws Exception; <span id="transmark"></s

随机推荐