Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Callable and Future in Java(java中的Callable和Future)

Callable and Future in Java(java中的Callable和Future)

作者头像
冬天里的懒猫
发布于 2020-09-28 03:17:18
发布于 2020-09-28 03:17:18
49310
代码可运行
举报
运行总次数:0
代码可运行

需要Callable的理由

通常,我们有两种方式创建线程,一种方式是继承Thread类,另外一种方式是实现Runnable接口。然而,Runnable方式缺少的一个特性就是,当线程终止的时候,即run运行完成的时候,我们布恩那个让线程返回一个执行结果。为了之处这个特性,在java中就增加了Callable接口。

Callable vs Runnable

  • 为了实现Runnable接口,需要实现不返回任何返回值的run方法,而对于callable,我们需要实现在完成的时候,返回接口的call方法,注意,线程不能用Callable创建,只能用Runnbale的方式创建。
  • 另外一个区别就是,call方法可以抛出异常。而run方法则不能。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Object call() throws Exception;

如下是Callable的代码示例,它将在大约0-4秒之后返回一个随机数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class CallableExample implements Callable {

	@Override
	public Object call() throws Exception {
		Random generator = new Random();
		Integer randomNumber = generator.nextInt(5);
		TimeUnit.SECONDS.sleep(randomNumber);

		return randomNumber;
	}
	
}

Future

当call方法执行完成的时候,计算结果必须存储在main线程的已知对象中,以便mian线程可以值得这个call线程的返回结果,但是程序在此后将如何存储和获得这个结果呢? 为此,我们需要使用Future丢箱,可以将Future看作一个持有结果的对象,它可能现在不持有结果,但是将来,一旦Callable执行完成,就会这样做,因此,Futrue基本上是利用主线程跟踪其他线程结果的一种方式,要实现这个接口,需要重写5个方法,以下示例是其具体实现,在此,我们只列出了重要的方法。 需要注意的是,Callable和Future做了两件不同的事情,Callable和Runnable类似,因为它封装了一个任务,该任务在另外一个线程上运行,而Future用于存储从另外一个线程获得的结果,事实上,未来也可以使用Runnable,这一点在Executors参与之后就会变得很清晰。

  • public boolean cancel(boolean mayInterrupt): 用于停止任务,如果任务尚未启动,他将停止该任务,如果任务已经启动,则在manInteerrupt为ture的时候中断该任务。
  • public Object get() throws InterruptedException, ExecutionException:用于获得任务的结果,如果任务完成,则立即返回结果,否则等待任务完成,然后返回结果。
  • public boolean isDone():如果任务完成,则返回true,否则,返回false。

如果需要创建线程,那么细羽一个Runnable,如果需要取得结果,那么需要一个Future。 在java中,具体的类似是FutureTask,它实现了Runnable和Future,方便地结合了这两种功能。 FutureTask可以通过为其提供的构造函数来创建Callable,然后将FutureTask对象提供给Thread的构造函数来创建Thread对象。因此,间接的实现了Callable创建线程。在此要重点强调的是,没有办法直接用Callable创建线程。 如下是Callable和FutureTask的完整示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class CallableExample implements Callable {

	@Override
	public Object call() throws Exception {
		Random generator = new Random();
		Integer randomNumber = generator.nextInt(5);
		TimeUnit.SECONDS.sleep(randomNumber);

		return randomNumber;
	}

}

public class CallableFutureTest {
	public static void main(String[] args) throws Exception
	{

		// FutureTask is a concrete class that
		// implements both Runnable and Future
		FutureTask[] randomNumberTasks = new FutureTask[5];

		for (int i = 0; i < 5; i++)
		{
			Callable callable = new CallableExample();

			// Create the FutureTask with Callable
			randomNumberTasks[i] = new FutureTask(callable);

			// As it implements Runnable, create Thread
			// with FutureTask
			Thread t = new Thread(randomNumberTasks[i]);
			t.start();
		}

		for (int i = 0; i < 5; i++)
		{
			// As it implements Future, we can call get()
			System.out.println(randomNumberTasks[i].get());

			// This method blocks till the result is obtained
			// The get method can throw checked exceptions
			// like when it is interrupted. This is the reason
			// for adding the throws clause to main
		}
	}
}

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2
2
3
4
0

线程启动后与它所有的交互都使用FutureTask对象来实现Future接口,因此,不需要存储线程对象,使用TutureTask对象,可以实现对task的取消,以及检查它释放完成或者尝试获得其执行结果。 如下是通过Runnable实现类型功能的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class RunnableExample implements Runnable {

	private Object result = null;

	@Override
	public void run() {
		Random generator = new Random();
		Integer randomNumber = generator.nextInt(5);

		// As run cannot throw any Exception
		try {
			Thread.sleep(randomNumber * 1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		// Store the return value in result when done
		result = randomNumber;

		// Wake up threads blocked on the get() method
		synchronized (this) {
			notifyAll();
		}
	}

	public synchronized Object get()
			throws InterruptedException {
		while (result == null) {
			wait();
		}

		return result;
	}
}

public class RunnableTest {

	public static void main(String[] args) throws Exception {
		RunnableExample[] randomNumberTasks = new RunnableExample[5];

		for (int i = 0; i < 5; i++) {
			randomNumberTasks[i] = new RunnableExample();
			Thread t = new Thread(randomNumberTasks[i]);
			t.start();
		}

		for (int i = 0; i < 5; i++) {
			System.out.println(randomNumberTasks[i].get());
		}
	}
}

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
4
4
0
2
3

参考

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/FutureTask.html

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

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

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

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

评论
登录后参与评论
1 条评论
热度
最新
主编的产量比生产队的驴都还高
主编的产量比生产队的驴都还高
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
强大到没朋友的mysql-shell及插件
mysql-shell 是官方出品的运维相关小工具, 目前已经具备很多功能。如果再配合大佬写的插件,简直强大到没朋友。
保持热爱奔赴山海
2020/08/09
1.5K1
新特性解读 | MySQL 8.0 增强逻辑备份恢复工具介绍
资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。
爱可生开源社区
2020/11/03
7440
新特性解读 | MySQL 8.0 增强逻辑备份恢复工具介绍
新特性解读 | MySQL8.0 ALTER TABLE … ALGORITHM=INSTANT
MySQL 8.0.29 之前,在线 DDL 操作中即时添加列只能添加在表的最后一列,对于在某个具体列后面快速添加列很不方便,MySQL 8.0.29 扩展了对 ALTER TABLE … ALGORITHM=INSTANT 的支持:用户可以在表的任何位置即时添加列、即时删除列、添加列时评估行大小限制。
爱可生开源社区
2022/09/26
2.5K0
新特性解读 | MySQL8.0 ALTER TABLE … ALGORITHM=INSTANT
技术分享 | 数据校验工具 pt-table-checksum
爱可生 DBA 团队成员,负责公司 DMP 产品的运维和客户 MySQL 问题的处理。对数据库技术有着浓厚的兴趣。你见过凌晨四点 MySQL 的 error 吗?
爱可生开源社区
2020/12/31
1.3K0
MySQL 8.0新特性 — 备份锁
在MySQL 8.0中,引入了一个轻量级的备份锁,这个锁可以保证备份一致性,而且阻塞的操作相对比较少,是一个非常重要的新特性,接下来我们就来了解一下。
brightdeng@DBA
2020/11/13
3.2K0
MySQL 8.0新特性 — 备份锁
MySQL 逻辑备份mysqldump&mysqlpump&mydumper原理解析
添加了--master-data FLUSH /!40101 LOCAL / TABLES FLUSH TABLES WITH READ LOCK SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ START TRANSACTION /!40100 WITH CONSISTENT SNAPSHOT / SHOW MASTER STATUS UNLOCK TABLES
星哥玩云
2022/08/18
2480
技术分享 | 可能是目前最全的 MySQL 8.0 新特性解读(上)
系统表全部换成事务型的innodb表,默认的MySQL实例将不包含任何MyISAM表,除非手动创建MyISAM表。
爱可生开源社区
2023/03/23
1.6K0
MySQL Shell 使用指南
MySQL Shell 是官方提供的 MySQL 周边适配组件,是新一代的高级客户端,在 MySQL 8.0 及其以后的版本得以慢慢推广应用。之前笔者因为 MySQL 8.0 用得比较少,一直没有详细使用过这个工具,近期在捣鼓 MySQL 8.0,趁此机会,一起来学习下吧。
MySQL技术
2024/06/13
3330
MySQL Shell 使用指南
【MySQL 8.0神器揭秘】派生表条件下推——让你的SQL飙车不再是梦想!
最近遇到了不少MySQL性能优化的案例,都和子查询有关,今天就这个话题做一定的分析。
MySQLSE
2024/01/22
5260
【MySQL 8.0神器揭秘】派生表条件下推——让你的SQL飙车不再是梦想!
MySQL 8.0 新特性:快速加列
变更表结构的是 DBA 经常会遇到的问题之一,在 MySQL 的环境中,一般会直接使用 Alter 语句来完成这些操作,这些 Alter 语句对应的操作通常也称之为 DDL 操作。
王文安@DBA
2020/10/20
4.1K0
MySQL 8.0 新特性:快速加列
MySQL从删库到恢复,还用跑路吗?
误删数据库应该如何恢复操作?怎样才能做好数据库的备份、恢复、容灾、HA?如果你身处数据库行业,最近可能会比较关注这几个问题
搜云库技术团队
2019/10/17
1.4K0
新特性解读 | MySQL8.0 ALTER TABLE …
MySQL 8.0.29之前,在线 DDL 操作中即时添加列只能添加在表的最后一列,对于在某个具体列后面快速添加列很不方便,MySQL 8.0.29 扩展了对 ALTER TABLE … ALGORITHM=INSTANT 的支持:用户可以在表的任何位置即时添加列、即时删除列、添加列时评估行大小限制。
爱可生开源社区
2022/08/11
1.2K0
技术分享 | 使用 sync_diff_inspector 对两个 MySQL 进行数据校验
sync-diff-inspector 是由 PingCAP 开源的数据校验工具,用于校验MySQL/TiDB中两份数据是否一致。
爱可生开源社区
2023/03/02
1.1K0
MySQL备份与恢复(二)
前天的文章中简单写了备份与恢复的方法,今天我们主要来看看不同的备份方法备份出来的文件结果,以及它们的恢复方法。
AsiaYe
2019/11/06
8750
故障分析 | DDL 导致的 Xtrabackup 备份失败
近日,客户反馈某生产业务系统凌晨的物理备份都失败了(一主二从的集群,仅在两个从库上做 Xtrabackup 全备,主库不参与备份),需排查备份失败的原因。
爱可生开源社区
2022/05/26
1.4K0
hhdb数据库介绍(9-21)
控制节点切换前是否先判断集群所有成员都能ping通,true开启false关闭。 例:A机房和B机房构成双活集群,A机房3个计算节点,B机房2个计算节点,primary节点在B机房。AB机房网络隔离后,A机房做为多数派会选出主,B机房无法形成多数派而cluster shutdown,但是在B机房primary未下线时,收到A机房主存储节点的心跳超时导致存储节点发生切换(开启此参数可避免此类情况)。
恒辉信达
2024/12/03
1180
分布式 | 利用 TiDB DM 将数据从 MySQL 迁移至 DBLE
某客户MySQL实例中数据较大(上T的数据量),需要将MySQL中数据全量/增量快速迁移至DBLE。TiDB DM支持多线程数据导出导入及增量同步,因此选择了TiDB DM为作数据迁移工具。本文以此案例为背景,介绍使用TiDB DM将数据从MySQL迁移至DBLE的方法及遇到的一些问题。
爱可生开源社区
2022/08/16
6890
故障分析 | mysqldump 搭建复制报错,竟然是因为这个!
爱可生 DBA 团队成员,熟悉 MySQL,TiDB,OceanBase 等数据库。相信持续把对的事情做好一点,会有不一样的收获。
爱可生开源社区
2023/08/18
6180
故障分析 | mysqldump 搭建复制报错,竟然是因为这个!
【DB宝43】MySQL误操作闪回恢复利器之my2sql
可以用于MySQL误操作闪回的工具包括my2sql、binlog2sql和MyFlash等工具,其中,个人感觉my2sql最好用。
AiDBA宝典
2021/03/25
2.5K0
【DB宝43】MySQL误操作闪回恢复利器之my2sql
MySQL 8.0新特性 — 不可见索引
在MySQL 8.0中,引入了不可见索引的新特性;不可见索引,是指实际存在但不会被优化器选用的索引。有童鞋就会问,不可见索引究竟有什么用?虽然在大多数情况下,业务系统新模块的上线,是需要经过充分测试;索引的创建与删除,也是需要经过测试环境的验证;但是生产环境的复杂性,有时候是测试环境无法完全模拟的,包括环境配置不一样、并发量不一样、模块间关联未充分测试等等。在这个时候,不可见索引的作用就体现出来了,它可以替代索引的创建与删除,并对其造成的性能影响进行充分验证,一旦出现系统性能急剧下降的情况,DBA可以进行快速回退,而不需要真正地重新创建或删除索引。
brightdeng@DBA
2020/09/22
1.4K0
MySQL 8.0新特性 — 不可见索引
推荐阅读
相关推荐
强大到没朋友的mysql-shell及插件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验