JavaEE(系列14) -- 多线程(Callable)

这篇具有很好参考价值的文章主要介绍了JavaEE(系列14) -- 多线程(Callable)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Callable接口

Callable 是一个 interface . 相当于把线程封装了一个 "返回值". 方便程序猿借助多线程的方式计算结果.

代码示例: 创建线程计算 1 + 2 + 3 + ... + 1000, 不使用 Callable 版本

思路:

  1. 创建一个类Result,包含 sum 表示最终结果, lock 表示线程同步使用的锁对象.
  2. main 方法中先创建 Result 实例, 然后创建一个线程 t. 在线程内部计算 1 + 2 + 3 + ... + 1000.
  3. 主线程同时使用 wait 等待线程 t 计算结束. (注意, 如果执行到 wait 之前, 线程 t 已经计算完了, 就不必等待了).
  4. 当线程 t 计算完毕后, 通过 notify 唤醒主线程, 主线程再打印结果.
static class Result {
  public int sum = 0;
  public Object lock = new Object();
}


public static void main(String[] args) throws InterruptedException {
  Result result = new Result();
  Thread t = new Thread() {
    @Override
    public void run() {
      int sum = 0;
      for (int i = 1; i <= 1000; i++) {
        sum += i;
     }
      synchronized (result.lock) {
        result.sum = sum;
        result.lock.notify();
     }
   }
 };
  t.start();
  synchronized (result.lock) {
    while (result.sum == 0) {
      result.lock.wait();
   }
    System.out.println(result.sum);
 }
}

 可以看到, 上述代码需要一个辅助类 Result, 还需要使用一系列的加锁和 wait notify 操作, 代码复杂, 容易出错.

代码示例: 创建线程计算 1 + 2 + 3 + ... + 1000, 使用 Callable 版本

思路:

  • 创建一个匿名内部类, 实现 Callable 接口. Callable 带有泛型参数. 泛型参数表示返回值的类型.
  • 重写 Callable 的 call 方法, 完成累加的过程. 直接通过返回值返回计算结果.
  • callable 实例使用 FutureTask 包装一下.
  • 创建线程, 线程的构造方法传入 FutureTask . 此时新线程就会执行 FutureTask 内部的 Callable 的call 方法, 完成计算. 计算结果就放到了 FutureTask 对象中.
  • 在主线程中调用 futureTask.get() 能够阻塞等待新线程计算完毕. 并获取到 FutureTask 中的结果.
package JUC;

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 {
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum = 0;
                for (int i = 0; i < 1000; i++) {
                    sum += i;
                }
                return sum;
            }
        };

        // 需要找一个人,来完成这个任务(需要线程去执行)
        // 在执行之前要进行一个包装,传入线程,启动任务
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        Thread t = new Thread(futureTask);
        t.start();

        // 获取上面t线程任务的返回值
        System.out.println(futureTask.get());
    }
}

 问题:我们可以发现,我们是在主线程中进行调用的get方法,那么如何保证在调用get之前,call方法就是执行完毕的了呢?


 答案: futureTask 的 get方法和join方法是类似的,都是会堵塞等待的,等待call方法执行完毕,get方法再进行返回call方法的返回值.

 理解Callable和FutureTask

理解 Callable

        Callable 和 Runnable 相对, 都是描述一个 "任务". Callable 描述的是带有返回值的任务,Runnable 描述的是不带返回值的任务.
Callable 通常需要搭配 FutureTask 来使用. FutureTask 用来保存 Callable 的返回结果. 因为Callable 往往是在另一个线程中执行的, 啥时候执行完并不确定.FutureTask 就可以负责这个等待结果出来的工作.

理解 FutureTask 

 

        想象去吃麻辣烫. 当餐点好后, 后厨就开始做了. 同时前台会给你一张 "小票" . 这个小票就是FutureTask. 后面我们可以随时凭这张小票去查看自己的这份麻辣烫做出来了没.文章来源地址https://www.toymoban.com/news/detail-459428.html

到了这里,关于JavaEE(系列14) -- 多线程(Callable)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 多线程(JavaEE初阶系列2)

    目录 前言: 1.什么是线程 2.为什么要有线程 3.进程与线程的区别与联系 4.Java的线程和操作系统线程的关系 5.多线程编程示例 6.创建线程 6.1继承Thread类  6.2实现Runnable接口 6.3继承Thread,使用匿名内部类 6.4实现Runnable接口,使用匿名内部类 6.5lambda表达式创建Runnable子类对象 7.

    2024年02月15日
    浏览(35)
  • JavaEE(系列8) -- 多线程案例(单例模式)

    目录 1. 设计模式 2. 单例模式 -- 饿汉模式 3. 单例模式 -- 懒汉模式  4. 单例模式(懒汉模式-多线程)  什么是设计模式?         设计模式好比象棋中的 \\\"棋谱\\\". 红方当头炮, 黑方马来跳. 针对红方的一些走法, 黑方应招的时候有一些固定的套路. 按照套路来走局势就不会吃亏

    2024年02月05日
    浏览(39)
  • 多线程-线程的创建的方式3、4:实现Callable与线程池

    简要概况: 案例: 输出: 现有问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。 那么,有没有一种办法使得线程可以复用,即执行完一个任务,并

    2024年02月09日
    浏览(44)
  • Callable接口和Future接口

    创建线程的方式 1.继承Thread类2.实现Runnable接口3.Callable接口4.线程池方式 Callable接口 在继承Thread类和实现Runnable接口的方式创建线程时,线程执行的run方法中,返回值是void,即无法返回线程的执行结果,为了支持该功能,java提供了Callable接口。 Callable和Runnable接口的区别 1.Ca

    2024年02月05日
    浏览(67)
  • 多线程-Runable和Callable的区别

    在Java中,多线程可以通过实现Runnable接口或使用Callable接口来实现。这两种方式有一些区别,如下所示: 返回值: Runnable接口的run()方法没有返回值,它表示一个没有返回结果的任务。 Callable接口的call()方法有返回值,可以返回计算结果。 异常处理: Runnable接口的run()方法不

    2024年02月14日
    浏览(36)
  • 多线程之Runnable 、Callable 、Thread

    Java 提供了三种创建线程方法: 通过实现 Runnable 接口; 通过继承 Thread 类本身; 通过 Callable 和 Future 创建线程。 创建一个线程,最简单的方法是创建一个实现 Runnable 接口的类。 为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下: 你可以重写该方法,重要的

    2024年02月07日
    浏览(50)
  • JUC-线程Callable使用与FutureTask源码阅读

    Callable简单使用 带返回值的线程(实现implements Callable返回值类型),使用示例 FutureTask面向对象方式学习 为了定义这样一个事物“有返回结果”,暂且称之为RunnableFuture。它集合了Runnable和Future两种事物 (其中Future接口 表示了一个任务的生命周期,是一个可取消的异步运算,可

    2024年02月04日
    浏览(33)
  • 从源码角度深入解析Callable接口

    摘要: 从源码角度深入解析Callable接口,希望大家踏下心来,打开你的IDE,跟着文章看源码,相信你一定收获不小。 本文分享自华为云社区《一个Callable接口能有多少知识点?》,作者: 冰 河。 并发编程一直是程序员们比较头疼的,如何编写正确的并发程序相比其他程序来

    2023年04月18日
    浏览(41)
  • JUC并发编程-集合不安全情况以及Callable线程创建方式

    1)List 不安全 ArrayList 在并发情况下是不安全的 解决方案 : 1.Vector 2.Collections.synchonizedList() 3. CopyOnWriteArrayList 核心思想 是,如果有 多个调用者(Callers)同时要求相同的资源 (如内存或者是磁盘上的数据存储),他们 会共同获取相同的指针指向相同的资源 , 直到某个调用者

    2024年01月23日
    浏览(45)
  • 常用Java代码-Java中的Future和Callable接口

    在Java中, Future 和 Callable 接口通常用于异步编程,特别是在 java.util.concurrent 包中。这两个接口常常一起使用, Callable 对象用于生产任务的结果,而 Future 用于表示可能还未完成的任务的结果。 以下是一个简单的示例,展示了如何使用这两个接口: 在这个例子中,我们创建了

    2024年02月02日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包