- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
线程任务编排指的是对多个线程任务按照一定的逻辑顺序或条件进行组织和安排,以实现协同工作、顺序执行或并行执行的一种机制.
有同学可能会想:那线程的任务编排是不是问的就是线程间通讯啊?
线程间通讯我知道了,它的实现方式总共有以下几种方式:
但是,线程通讯和线程的任务编排是不同的两个概念,它们的区别如下:
简而言之,线程任务编排侧重于高层次的执行计划和流程控制,而线程通讯则专注于底层的数据交互和同步细节。在实际应用中,有效的线程任务编排往往离不开合理的线程通讯机制,两者相辅相成,共同支撑起复杂多线程程序的正确执行.
线程的任务编排的实现方式主要有以下两种:
FutureTask 使用示例如下:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FutureTaskDemo {
public static void main(String[] args) {
// 创建一个Callable任务
Callable<Integer> task = () -> {
Thread.sleep(2000); // 模拟任务耗时操作
return 10; // 返回任务结果
};
// 创建FutureTask,并将Callable任务包装起来
FutureTask<Integer> futureTask = new FutureTask<>(task);
// 创建线程池
ExecutorService executor = Executors.newCachedThreadPool();
// 提交FutureTask给线程池执行
executor.submit(futureTask);
try {
// 获取任务结果,get()方法会阻塞直到任务完成并返回结果
int result = futureTask.get();
System.out.println("任务结果:" + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
在上述示例中,通过创建一个 Callable 任务来模拟耗时操作,并使用 FutureTask 包装该任务。然后将 FutureTask 提交给线程池执行,最后通过 get() 方法获取任务的执行结果,之后才会执行后续流程。我们可以通过 get() 方法阻塞等待程序执行结果,从而完成线程任务的简单编排.
从上面 FutureTask 实现代码可以看出,它不但写法麻烦,而且需要使用 get() 方法阻塞等待线程的执行结果,对于异步任务的执行来说,不够灵活且效率也会受影响,然而 CompletableFutrue 的出现,则弥补了 FutureTask 的这些缺陷.
CompletableFutrue 提供的方法有很多,但最常用和最实用的核心方法只有以下几个: 例如,我们现在实现一个这样的场景: 任务描述:任务一执行完之后执行任务二,任务三和任务一和任务二一起执行,所有任务都有返回值,等任务二和任务三执行完成之后,再执行任务四,它的实现代码如下:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) {
// 任务一:返回 "Task 1 result"
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
try {
// 模拟耗时操作
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
return "Task 1 result";
});
// 任务二:依赖任务一,返回 "Task 2 result" + 任务一的结果
CompletableFuture<String> task2 = task1.handle((result1, throwable) -> {
try {
// 模拟耗时操作
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
return "Task 2 result " + result1;
});
// 任务三:和任务一、任务二并行执行,返回 "Task 3 result"
CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> {
try {
// 模拟耗时操作
Thread.sleep(800); // 任务三可能比任务二先完成
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
return "Task 3 result";
});
// 任务四:依赖任务二和任务三,等待它们都完成后执行,返回 "Task 4 result" + 任务二和任务三的结果
CompletableFuture<String> task4 = CompletableFuture.allOf(task2, task3).handle((res, throwable) -> {
try {
// 这里不需要显式等待,因为 allOf 已经保证了它们完成
return "Task 4 result with " + task2.get() + " and " + task3.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
});
// 获取任务四的结果并打印
String finalResult = task4.join();
System.out.println(finalResult);
}
}
使用 CompletableFuture 需要配合线程池一起使用吗?为什么?CompletableFuture 默认的线程池是如何实现的?
本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块.
最后此篇关于美团面试:如何实现线程任务编排?的文章就讲到这里了,如果你想了解更多关于美团面试:如何实现线程任务编排?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
总览 数据库的数据存储有两种类型,一种是面向行的(row-oriented)数据库,另一种是面向列的(column-oriented )数据库。 面向行(事务型) 数据库 该类数据库是根据
starting from a joke 问:把大象放冰箱里,分几步? 答:三步啊,第1、把冰箱门打开,第2、把大象放进去,第3、把冰箱门带上。 问:实现spring事务,分几步? 答:三
在最近的一次采访中,我有这个问题。 这里有什么错误?我知道足够的 c#,但我看不到错误。可以吗? Class x { protected string t1; public int
我在面试中被要求设计一个文件系统,允许用户将自己的属性添加到文件和文件夹中。我刚刚说过要将属性添加到文件描述符并允许根据此属性标准搜索文件,以及添加此属性以显示在文件/文件夹详细信息中。 看起来面试官
我一直在面试,下面应该有什么问题? 我可以假设这是您无法检查类是否为空的问题,对吗?!谢谢! public class NiceActivity extends Activity { priv
给定一个数组,如何返回总和为偶数的对数? 例如: a[] = { 2 , -6 , 1, 3, 5 } 在这个数组中,偶数和的对数是(2,-6), (1,3) , (1,5), (3,5) 函数应返回
这个问题是在面试中被问到的 Assume you have a dictionary of words: (use if you have /usr/share/dict/words). Given
我被要求实现 invert(x,p,n) 返回 x 的 n 位开始于位置 p 反转(即 1 变为 0,反之亦然),其他不变。 我的解决方案是: unsigned invert(unsigned x,
有人问我这个问题:给定一个大小为 n 的 int 和 int sum 的数组,我需要返回数组元素的所有对,其总和等于 总和 std::vector > find(int* arr,size_t n,i
我在一次面试中遇到了这个问题。有一组对象与起始值和结束值相关联。与每个对象相关联的计数是具有较长开始时间和较短结束时间的其他对象的数量。所以我必须找到与每个对象关联的计数。 我提出了 O(n^2) 解
我今天在采访中被问到这个问题。我已经尝试了一种解决方案,但想知道是否有更好的方法来解决这个问题: 问题:我有一个包含 500,000 个元素的数组列表,这样数组列表的每个元素的值都与索引相同。例如:l
有一个包含白色单元格,黑色单元格和只有一个灰色单元格的矩阵,需要从 (0,0) 到 (N-1, N-1) 如果 Arra[N][N]约束:A。该路径应该只覆盖白色单元格并且应该通过灰色单元格。b.访问
给定一个正整数数组,找出排列的任意排列可以形成的最大值。我想知道是否有更好的数据结构可以为问题提供更优雅的解决方案。 import java.util.ArrayList; import java.u
我在面试中被问到以下问题(不幸的是我找不到比 N^2 更好的答案) 对于大小为 N 的 unsigned int 的给定数组 arr,对于每个元素(在索引 i 中)我应该返回一个元素在索引 j (j
极点:数组中左侧元素小于或等于它且右侧元素大于或等于它的元素。 示例输入 3,1,4,5,9,7,6,11 期望的输出 4,5,11 面试时被问到这个问题,要返回元素的索引,只返回第一个满足条件的元素
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我今天被问到这个问题,我知道答案很简单,但他让我一直到最后。 问题 编写程序删除存储在 ArrayList 中的偶数,其中包含 1 - 100。 我只是说哇 给你,这就是我的实现方式。 ArrayLi
我在一次采访中遇到了这个问题,完全被难住了。我能想到的唯一解决方案是将 currentAngle 存储在 NSArray 中以计算下一个角度。 问题:使用 iPhone 的指南针在屏幕上移动一个 35
我必须在接下来的几周内采访一些 C++ 候选人,作为公司最资深的程序员,我应该尝试弄清楚这些人是否知道他们在做什么。 那么有人有什么建议吗? 就我个人而言,我讨厌被留在房间里填写一些 C++ 问题,所
消息队列(MQ),一种能实现生产者到消费者单向通信的通信模型,这也是现在常用的主流中间件。 常见有 RabbitMQ、ActiveMQ、Kafka等 他们的特点也有很多 比如 解偶、异步、广播
我是一名优秀的程序员,十分优秀!