Future
Future是一个占位符,它代表一个尚未完成但将来会完成的计算结果。你可以把它想象成一张“取餐小票”:你点完咖啡,服务员给你一张小票。这张小票不是咖啡本身,但它承诺未来你会凭此拿到咖啡。在小票有效期间(计算进行中),你可以去做其他事(不阻塞主线程),等咖啡做好了,你再凭票取咖啡(获取结果)。Kotlin 的Deferred= 协程版的 Future,用async创建,await()等待不阻塞线程a
Future” 在计算机科学,尤其是在并发编程和异步编程中,是一个非常核心且经典的概念。
一、定义
Future 是一个占位符,它代表一个尚未完成但将来会完成的计算结果。
你可以把它想象成一张“取餐小票”:你点完咖啡,服务员给你一张小票。这张小票不是咖啡本身,但它承诺未来你会凭此拿到咖啡。在小票有效期间(计算进行中),你可以去做其他事(不阻塞主线程),等咖啡做好了,你再凭票取咖啡(获取结果)。
二、Future 的核心状态与行为
一个典型的 Future 在生命周期中通常经历三种状态:
-
Pending(进行中):任务正在执行,结果尚未产生。
-
Completed(已完成):
-
Success(成功):任务正常结束,产生了有效值。
-
Failure(失败):任务抛出异常,产生了错误。
-
核心行为:
-
获取结果:通常通过
.get()或.result()等方法。但注意,在纯粹的异步模型中,调用get()会阻塞当前线程直到结果就绪。现代的非阻塞模型更倾向于通过回调或组合器来处理。 -
添加回调:如
onComplete,当 Future 完成时自动执行回调。 -
组合变换:如
map,flatMap,filter等,允许将多个 Future 像集合一样进行操作。
三、Future 的两种执行模式
这是初学者容易混淆的点,必须区分:
-
热执行(Eager Execution)
-
一旦你创建一个 Future,任务立即在后台开始执行。
-
如:
CompletableFuture.supplyAsync(),Scala Future,Python concurrent.futures.
-
-
冷执行(Lazy Execution)
-
创建 Future 时只是定义了一个计算,并不执行。需要调用
await或交给执行器才会执行。 -
如:
Rust Future,Java 8 Stream,Kotlin Flow.
-
四、例子
Java 8+
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class FutureDemo {
public static void main(String[] args) {
// 开始时间
long start = System.currentTimeMillis();
// 1. 异步获取用户
CompletableFuture<User> userFuture = CompletableFuture.supplyAsync(() -> {
sleep(1000); // 模拟耗时1秒
System.out.println("线程: " + Thread.currentThread().getName() + " 获取到用户");
return new User(1001, "张三");
});
// 2. 拿到用户后,异步获取他的订单
CompletableFuture<Order> orderFuture = userFuture.thenCompose(user ->
CompletableFuture.supplyAsync(() -> {
sleep(800); // 模拟耗时0.8秒
System.out.println("线程: " + Thread.currentThread().getName()
+ " 获取到用户 " + user.getId() + " 的订单");
return new Order(50001, user.getId(), 299.00);
})
);
// 3. 同时查询系统配置(完全不依赖前面)
CompletableFuture<Config> configFuture = CompletableFuture.supplyAsync(() -> {
sleep(500); // 模拟耗时0.5秒
System.out.println("线程: " + Thread.currentThread().getName() + " 获取到系统配置");
return new Config("vip_discount", 0.8);
});
// 4. 等用户订单和配置都准备好,计算最终价格
CompletableFuture<String> resultFuture = orderFuture.thenCombine(configFuture,
(order, config) -> {
double finalPrice = order.getAmount() * config.getDiscount();
return String.format("用户 %s 的订单 %d 最终价格: %.2f",
userFuture.join().getName(), order.getId(), finalPrice);
}
);
// 5. 最终结果回调
resultFuture.whenComplete((result, error) -> {
if (error == null) {
System.out.println("✓ 成功: " + result);
} else {
System.err.println("✗ 失败: " + error.getMessage());
}
System.out.println("总耗时: " + (System.currentTimeMillis() - start) + "ms");
});
// 6. 主线程等待一下(否则程序直接退出了)
sleep(2000);
}
static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class User {
private int id; private String name;
User(int id, String name) { this.id = id; this.name = name; }
int getId() { return id; }
String getName() { return name; }
}
static class Order {
private int id; private int userId; private double amount;
Order(int id, int userId, double amount) {
this.id = id; this.userId = userId; this.amount = amount;
}
int getId() { return id; }
double getAmount() { return amount; }
}
static class Config {
private String key; private double discount;
Config(String key, double discount) { this.key = key; this.discount = discount; }
double getDiscount() { return discount; }
}
}
运行结果:
线程: ForkJoinPool.commonPool-worker-1 获取到用户
线程: ForkJoinPool.commonPool-worker-2 获取到系统配置
线程: ForkJoinPool.commonPool-worker-1 获取到用户 1001 的订单
✓ 成功: 用户 张三 的订单 50001 最终价格: 239.20
总耗时: 1023ms
Kotlin
Kotlin 推荐使用协程而不是传统的 Future。它的异步结果类型叫 Deferred<T>,可以理解为 Kotlin 版的 Future,但更轻量、更强大。
看下面这个完整的电商订单处理例子:
import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis
// 数据类
data class User(val id: Int, val name: String)
data class Order(val id: Int, val userId: Int, val amount: Double)
data class Config(val key: String, val discount: Double)
data class Product(val id: Int, val name: String, val price: Double)
fun main() = runBlocking {
println(" 开始处理订单...")
val totalTime = measureTimeMillis {
processOrder()
}
println(" 总耗时: ${totalTime}ms")
}
suspend fun processOrder() {
coroutineScope {
// ========== 1. 创建 Deferred(相当于 Future) ==========
val userDeferred: Deferred<User> = async {
fetchUser()
}
val configDeferred: Deferred<Config> = async {
fetchConfig()
}
// ========== 2. 等待用户结果 ==========
val user = userDeferred.await() // 非阻塞等待
println(" 已获取用户: ${user.name}")
// ========== 3. 依赖上一个结果 ==========
val orderDeferred: Deferred<Order> = async {
fetchOrder(user.id)
}
// ========== 4. 并发获取商品详情 ==========
val productsDeferred: Deferred<List<Product>> = async {
fetchRecommendedProducts(user.id)
}
// ========== 5. 等待所有结果 ==========
val order = orderDeferred.await()
val config = configDeferred.await()
val products = productsDeferred.await()
// ========== 6. 组合结果 ==========
val finalPrice = order.amount * config.discount
println("""
订单详情:
- 订单号: ${order.id}
- 用户: ${user.name}
- 原价: ¥${order.amount}
- 折扣: ${config.discount * 10}折
- 最终价: ¥${"%.2f".format(finalPrice)}
- 推荐商品: ${products.joinToString { it.name }}
""".trimIndent())
}
}
// 模拟耗时操作(都加了延迟)
suspend fun fetchUser(): User {
delay(1000) // 模拟网络请求
println(" ✓ 用户服务: 查询完成")
return User(1001, "张三")
}
suspend fun fetchOrder(userId: Int): Order {
delay(800)
println(" ✓ 订单服务: 用户 $userId 订单查询完成")
return Order(50001, userId, 299.00)
}
suspend fun fetchConfig(): Config {
delay(500)
println(" ✓ 配置服务: 获取折扣配置")
return Config("vip_discount", 0.8)
}
suspend fun fetchRecommendedProducts(userId: Int): List<Product> {
delay(600)
println(" ✓ 推荐服务: 获取用户 $userId 的推荐商品")
return listOf(
Product(1, "无线鼠标", 89.9),
Product(2, "机械键盘", 299.0),
Product(3, "显示器支架", 159.0)
)
}
运行结果:
开始处理订单...
✓ 配置服务: 获取折扣配置
✓ 用户服务: 查询完成
已获取用户: 张三
✓ 订单服务: 用户 1001 订单查询完成
✓ 推荐服务: 获取用户 1001 的推荐商品
订单详情:
- 订单号: 50001
- 用户: 张三
- 原价: ¥299.0
- 折扣: 8.0折
- 最终价: ¥239.20
- 推荐商品: 无线鼠标, 机械键盘, 显示器支架
总耗时: 1023ms
Kotlin Deferred 核心用法
1. 创建 Deferred(3种方式)
// 方式1: async 构建器(最常用)
val deferred: Deferred<String> = async {
delay(1000)
"Hello"
}
// 方式2: CompletableDeferred(手动控制)
val completable = CompletableDeferred<String>()
// 在其他地方完成
completable.complete("World")
// 或带异常
// completable.completeExceptionally(Exception("出错了"))
// 方式3: future {}(与Java Future互操作)
val javaFuture: CompletableFuture<String> = CompletableFuture.supplyAsync { "Java" }
val kotlinDeferred: Deferred<String> = javaFuture.asDeferred() // 扩展函数
2. 等待结果
// await() - 挂起直到结果就绪(非阻塞)
val result = deferred.await()
// awaitAll() - 等待多个
val results = awaitAll(deferred1, deferred2, deferred3)
// join() - 不关心返回值,只等完成
deferred.join()
3. 并发模式
suspend fun concurrentExample() = coroutineScope {
// 并行执行(同时发起)
val deferred1 = async { task1() }
val deferred2 = async { task2() }
val deferred3 = async { task3() }
// 等待所有完成
val (result1, result2, result3) = awaitAll(deferred1, deferred2, deferred3)
// 或只等最快的那个
val firstCompleted = select<Deferred<String>> {
deferred1.onAwait { it }
deferred2.onAwait { it }
}.await()
}
Future vs Deferred 对比
| 特性 | Java CompletableFuture | Kotlin Deferred |
|---|---|---|
| 阻塞方式 | .get() 阻塞线程 |
.await() 挂起协程(不阻塞线程) |
| 内存开销 | 每个Future一个线程(或线程池) | 极轻量,挂起无线程占用 |
| 组合语法 | .thenCompose().thenCombine() |
直接用 await(),像同步代码 |
| 取消 | .cancel(true) |
.cancel() |
| 超时 | .orTimeout(1, TimeUnit.SECONDS) |
withTimeout(1000) { deferred.await() } |
| 异常处理 | .exceptionally() |
try-catch 包围 await() |
Kotlin 特有的强大模式
1. 结构化并发(自动取消)
suspend fun structuredConcurrency() = coroutineScope {
// 如果任何一个子协程失败,所有其他子协程自动取消
val user = async { fetchUser() }
val order = async { fetchOrder(user.await().id) } // 这里如果user失败,order自动取消
try {
println(order.await())
} catch (e: Exception) {
// user 或 order 任何一个出异常都会到这里
println("处理失败,所有任务已取消")
}
// 所有async任务在这里自动完成清理
}
2. 超时控制
suspend fun withTimeoutExample() = coroutineScope {
val deferred = async {
delay(2000)
"慢速任务"
}
try {
// 最多等1秒
withTimeout(1000) {
val result = deferred.await()
println(result)
}
} catch (e: TimeoutCancellationException) {
println(" 超时了,自动取消")
// deferred 自动被取消
}
}
3. Flow - 多个值的异步流
如果 Future 代表一个异步值,那 Flow 就是多个异步值:
fun stockPrices(): Flow<Double> = flow {
val prices = listOf(100.0, 101.5, 102.3, 101.8, 103.2)
for (price in prices) {
delay(1000) // 每秒推送一次价格
emit(price) // 发射值
}
}
suspend fun flowExample() {
stockPrices()
.map { it * 0.9 } // 转换
.filter { it > 90 } // 过滤
.take(3) // 只取前3个
.collect { price ->
println("当前股价: $price")
}
}
实战:模拟外卖订单系统
import kotlinx.coroutines.*
import kotlin.random.Random
data class OrderRequest(val foodId: Int, val address: String)
data class Payment(val orderId: String, val success: Boolean)
data class Delivery(val orderId: String, val estimatedTime: Int)
suspend fun main() = runBlocking {
println(" 外卖系统启动...\n")
val orders = listOf(
OrderRequest(101, "北京市朝阳区"),
OrderRequest(102, "上海市浦东新区"),
OrderRequest(103, "广州市天河区")
)
val startTime = System.currentTimeMillis()
// 并发处理多个订单
val results = orders.map { order ->
async {
processOrder(order)
}
}.awaitAll()
println("\n 所有订单处理完成,总耗时: ${System.currentTimeMillis() - startTime}ms")
results.forEachIndexed { index, result ->
println("订单${index + 1}: $result")
}
}
suspend fun processOrder(request: OrderRequest): String = coroutineScope {
println(" 开始处理订单: ${request.foodId}")
// 1. 并行执行:支付和餐厅备餐
val paymentDeferred = async {
processPayment(request)
}
val restaurantDeferred = async {
prepareFood(request.foodId)
}
// 2. 等待支付和备餐都完成
val payment = paymentDeferred.await()
val food = restaurantDeferred.await()
if (!payment.success) {
return@coroutineScope " 支付失败"
}
// 3. 开始配送
val delivery = async {
dispatchDelivery(request.address)
}.await()
" 已送达,${food},预计${delivery.estimatedTime}分钟"
}
suspend fun processPayment(request: OrderRequest): Payment {
delay(500) // 模拟支付处理
return Payment(
orderId = "ORD${Random.nextInt(1000, 9999)}",
success = Random.nextDouble() > 0.1 // 90%成功率
)
}
suspend fun prepareFood(foodId: Int): String {
delay(800) // 模拟备餐
return when (foodId) {
101 -> "汉堡套餐"
102 -> "披萨"
103 -> "寿司"
else -> "未知美食"
}
}
suspend fun dispatchDelivery(address: String): Delivery {
delay(600) // 模拟找骑手
return Delivery(
orderId = "DEL${Random.nextInt(1000, 9999)}",
estimatedTime = Random.nextInt(20, 40)
)
}
关键总结
-
Kotlin 的
Deferred= 协程版的 Future,用async创建,await()等待 -
不阻塞线程:
await()是挂起点,不是阻塞点 -
结构化并发:
coroutineScope自动管理生命周期,取消会传播 -
比 Java Future 更轻量:10万个并发任务也没问题
-
语法更简洁:不用写一长串链式调用,直接
val result = deferred.await()
什么时候用 async?
-
需要并发执行多个独立任务
-
需要等待结果并继续处理
-
任务之间有依赖关系
什么时候不用?
-
顺序执行 → 直接
suspend fun挨个调用 -
不需要返回值 → 用
launch -
多个异步值 → 用
Flow
这就是 Kotlin 风格的 Future,既保留了异步非阻塞的优点,又让代码像同步一样直观。
更多推荐

所有评论(0)