Java【多线程】Callable 是什么, 如何使用并理解 Cllable, 和 Runnable 有什么区别?

news2024/10/3 10:32:51

文章目录

  • 前言
  • 一、Callable 是什么?
  • 二、不使用 Callable 如何创建“有返回值的”线程?
  • 三、如何使用 Callable?
  • 四、如何理解 Callable?
  • 总结


前言

📕各位读者好, 我是小陈, 这是我的个人主页
📗小陈还在持续努力学习编程, 努力通过博客输出所学知识
📘如果本篇对你有帮助, 烦请点赞关注支持一波, 感激不尽
📙 希望我的专栏能够帮助到你:
JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等
Java数据结构: 顺序表, 链表, 堆, 二叉树, 二叉搜索树, 哈希表等
JavaEE初阶: 多线程, 网络编程, TCP/IP协议, HTTP协议, Tomcat, Servlet, Linux, JVM等(正在持续更新)

这篇文章 介绍了线程的概念和线程的创建方式(继承 Thread 类或实现 Runnable 接口), 本篇介绍另一种创建线程的方式 : 还可以实现 Cllable 接口


提示:是正在努力进步的小菜鸟一只,如有大佬发现文章欠佳之处欢迎批评指点~ 废话不多说,直接上干货!

一、Callable 是什么?

Callable 是一个函数式接口, 也是用于创建线程, 把线程封装了一个 “返回值”, 方便程序猿借助多线程的方式计算结果

无论是继承 Thread 类还是实现 Runnable 接口, 都是重写 run() 方法来描述一个线程执行的工作, 形如 :

    @Override
    public void run() {
        System.out.println("这里是线程运行的代码");
   }

可以看到 run() 方法是没有返回值的


二、不使用 Callable 如何创建“有返回值的”线程?

例如我们要计算 0~100 累加的和

  • 创建一个类 Result , 包含一个 sum 表示最终结果, 以及一个 lock 表示线程同步使用的锁对象
  • main 方法中先创建 Result 实例, 然后创建一个线程 t. 在线程内部计算 1 + 2 + 3 + … + 100
  • 主线程同时使用 wait() 等待线程 t 计算结束
  • 当线程 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) {
        	// 等待 t 线程计算完之后唤醒当前阻塞状态
            result.lock.wait();
       }
        System.out.println(result.sum);
   }
}

虽然这种方式也获取到了线程执行完毕的结果, 但本质上并不是作为返回值的, 而是两个线程修改了同一个变量, 这个变量是 result 类的成员属性, 并且实现的过程比较复杂

所以如果需要获取一个线程执行完毕的结果, 使用 Callable 更方便不易出错


三、如何使用 Callable?

还是计算 0~100 累加的和

  • 创建一个匿名内部类, 实现 Callable 接口, Callable 带有泛型参数, 泛型参数表示返回值的类型
  • 重写 Callable 的 call() 方法, 描述线程执行的工作, 通过返回值返回计算结果
  • 创建 FutureTask 类, 构造方法的参数是 callable 实例
  • 创建 Thread 类(线程), 构造方法的参数是 futureTask 实例, 此时新线程就会执行 FutureTask 内部的 Callable 的 call() 方法, 完成计算, 计算结果就放到了 FutureTask 对象中
  • 在主线程中调用 futureTask.get() 能够阻塞等待新线程计算完毕. 并获取到 FutureTask 中的结果
Callable<Integer> callable = new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 1000; i++) {
            sum += i;
        }
        return sum;
   }
};
FutureTask<Integer> futureTask = new FutureTask<>(callable);
Thread t = new Thread(futureTask);
t.start();
int result = futureTask.get();
System.out.println(result);

Callable 和 Runnable 同样是函数式接口, 所以也支持 lambda 表达式的写法

FutureTask<Integer> futureTask = new FutureTask<>( ()->{
	int sum = 0;
	for (int i = 1; i <= 1000; i++) {
		sum += i;
	}
	return sum;
});
Thread t = new Thread(futureTask);
t.start();
int result = futureTask.get();
System.out.println(result);

四、如何理解 Callable?

在这里插入图片描述

  • Callable 是一个接口, 需要重写 call() 方法, 这个方法相当于 Thread 和 Runnable 的 run(), 都是用来描述一个线程要执行的工作, call() 有返回值, run() 没有返回值
  • FutureTask 只是作为一层包装, 就相当于获取返回值的 “凭证”

总结

以上就是本篇的全部内容, 主要介绍了使用 Callable 接口来创建有返回值的线程

基本步骤 :

  • 创建一个类, 实现 Callable 接口
  • 重写 Callable 的 call() 方法
  • 创建 FutureTask 类
  • 创建 Thread 类
  • 调用 futureTask.get()

如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦😋😋😋~


上山总比下山辛苦
下篇文章见

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/982912.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

将钉钉机器人小程序从一个公司迁移至另一个公司的步骤

引言&#xff1a; 由于我们以前开发的钉钉小程序都在一个公司&#xff0c;想在想应用到另一个公司&#xff0c;这就牵扯出了关于钉钉小程序迁移方面的具体步骤。下面是具体步骤&#xff1a; 1、创建一个钉钉小程序 在这一步你需要有钉钉开放平台的开发者权限&#xff0c;具体…

uniapp使用@microsoft/signalr(报错“ReferenceError: require is not defined“)

后台老哥要用微软的signalr&#xff0c;总结了一些经验和问题 引入方法 1、npm npm i microsoft/signalr 2、下载他的js或者cdn <script src"https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>在uniapp中&…

无涯教程-JavaScript - BITRSHIFT函数

描述 BITRSHIFT函数返回一个右移指定位数的数字。 语法 BITRSHIFT (number, shift_amount)争论 Argument描述Required/OptionalnumberMust be an integer greater than or equal to 0.Requiredshift_amountMust be an integer.Required Notes 向右移动数字等效于从数字的二…

向你推荐 6 个很酷很实用的 Python 编码技巧

近年来&#xff0c;Python 编码技能的需求不断增长。在本作者前面文章介绍的多种基础上&#xff0c;我们整理了 6 个很酷很实用的 Python 编码技巧&#xff0c;您可以使用它们来改进代码、提高 Python 技能。 1.变量 在 Python 中&#xff0c;我们不需要使用临时变量&#xf…

stc单片机外部中断+EC11编码器实现计数功能

stc单片机外部中断+EC11编码器实现计数功能 🎬 串口输出测试效果: 📑EC11编码器原理图: 🍁EC11编码器输出信号说明: 📗检测说明: 📑以EC11-A信号作为一个时钟基准信号,检测到EC11-A之后,再去判断B的动作,一个相对的电平。当检测到A信号下降沿触发后,检测…

无涯教程-JavaScript - BITXOR函数

描述 BITXOR函数返回两个数字的按位" XOR"。 语法 BITXOR (number1, number2)争论 Argument描述Required/Optionalnumber1Must be greater than or equal to 0.Requirednumber2Must be greater than or equal to 0.Required Notes BITXOR返回一个十进制数字,该数…

Chrome 108版(64-bit 108.0.5359.125)网盘下载

还在用Selenium的朋友们注意了&#xff0c;目前Chrome的最新版是116&#xff0c;而官方的Chromedriver只支持到115版。 可惜Google不提供旧版Chrome的下载方式&#xff0c;需要旧版的很难回去了。如果真的想要旧版的Chrome&#xff0c;只能民间自救。 我在2022年12月备份了C盘…

Android 播放mp3文件

1&#xff0c;在res/raw中加入mp3文件 2&#xff0c;实现播放类 import android.content.Context; import android.media.AudioManager; import android.media.SoundPool; import android.util.Log;import java.util.HashMap; import java.util.Map;public class UtilSound {pu…

NIFI关于Variables的使用

说明 NIFI中的变量&#xff08;variables&#xff09;和参数&#xff08;parameters&#xff09;在引用的时候是有区别的。 参数的引用是使用#{参数名}的形式。 变量是使用${变量名}的形式来引用。 nifi版本&#xff1a;1.23.2&#xff08;docker镜像&#xff09; Variable…

【ViT(Vision Transformer)】(一) 中英双语

ViT&#xff08;Vision Transformer&#xff09; ABSTRACT1 INTRODUCTION2 RELATED WORK4 EXPERIMENTS4.1 SETUP4.2 COMPARISON TO STATE OF THE ART4.3 PRE-TRAINING DATA REQUIREMENTS 5 CONCLUSION4.4 SCALING STUDY4.5 INSPECTING VISION TRANSFORMER 5 CONCLUSION声明 ABS…

SCRUM敏捷产品负责人(CSPO)认证培训课程

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架。产品负责人是Scrum的三个角色之一&#xff0c;产品负责人在Scrum产品开发当中扮演舵手的角色&#xff0c;他决定产品的愿景、路线图以及投资回报&#xff0c;他需要回答…

正中优配:股市营业时间?

股市经营时间是指股票买卖商场的开放时间&#xff0c;每个国家、区域的股市经营时间都不同。股市经营时间确实定是由国家和商场交通情况、买卖商的需求等多种要素归纳考虑而得出的。本文将从股市经营时间的重要性、不同国家和区域的股市经营时间、股市经营时间影响股民的出资心…

运维事故减少80%,工单和值守服务上大分

“相比较系统上线之前&#xff0c;事故降低了80%&#xff0c;我们运维工程师时间节约40%&#xff01; ”福建某企业信息部沈工说。 “监控系统如果没有工单服务台&#xff0c;发现问题&#xff0c;没有解决问题方案&#xff0c;也没闭环的服务流程&#xff0c;那事实上没有起到…

深信服应用交付报表系统任意文件读取漏洞复现

文章目录 深信服应用交付报表系统任意文件读取漏洞复现0x01 前言0x02 漏洞描述0x03 影响范围0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 深信服应用交付报表系统任意文件读取漏洞复现 0x01 前言 本次测试仅供学习使用&#xff0c;如若非法他用&…

说说BTree和B+Tree

分析&回答 B树索引是B树在数据库中的一种实现&#xff0c;是最常见也是数据库中使用最为频繁的一种索引。B树中的B代表平衡&#xff08;balance&#xff09;&#xff0c;而不是二叉&#xff08;binary&#xff09;&#xff0c;因为B树是从最早的平衡二叉树演化而来的。 接…

第二证券:股吧沸腾!AI算力新龙头来了?

9月6日晚间&#xff0c;中贝通讯披露公告&#xff0c;公司与青海联通签定算力服务结构协议&#xff0c;青海联通拟向中贝通讯批量收买AI算力服务&#xff0c;服务费总金额为3.46亿元&#xff08;含税&#xff09;。 到9月6日&#xff0c;中贝通讯报27.58元/股&#xff0c;最新…

正中优配:国内怎么买美股?

近年来&#xff0c;随着我国经济的发展和对全球金融市场的越来越深入的了解&#xff0c;越来越多的投资者开始重视美国股市。而想要在国内购买美国股票并不是一件简单的事情&#xff0c;本文将从多个视点进行剖析。 一、注册海外买卖账户 在国内购买美股的条件是需求注册海外买…

Spring boot环境搭建

使用IDE工具&#xff1a;IntelliJ IDEA 目录 一、安装JAVA 二、安装maven&#xff08;Java项目管理工具&#xff09; 三、安装IDE 四、在IDE中配置spring boot项目环境 1、配置jdk 2、配置maven 3、安装创建spring boot项目插件&#xff1a;Spring Assistant 4、安装简…

使用Smartctl脚本输入当前所有磁盘的状态

一、安装Smartctl yum install smartmontools 二、写一个脚本输出当前所有磁盘的状态并且按名称分别写入到文件中 #!/bin/bashfor dev in $(lsblk -l | grep disk | awk {print $1}) doecho "检测磁盘 $dev"smartctl -a /dev/$dev > $dev.smartctl done 以下是这…

基于SpringBoot+thymeleaf的物资管理系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 这是一个物资管理系统…