假设需要并发执行 10,000 个非阻塞延迟任务(如模拟定时请求):
ExecutorService executor = Executors.newFixedThreadPool(64); // 最多 64 线程
List<Future<?>> futures = new ArrayList<>();
for (int i = 0; i < 10_000; i++) {
futures.add(executor.submit(() -> {
Thread.sleep(100); // 阻塞线程
return null;
}));
}
// 需要手动等待所有 Future 完成
(10000/64)*100ms ≈ 15.6s
。Observable.range(1, 10_000)
.flatMap(i ->
Observable.just(i)
.delay(100, TimeUnit.MILLISECONDS, Schedulers.io())
)
.subscribe();
delay
内部使用线程池调度,同样受限于 Schedulers.io()
的线程数(默认无上限,但实际受系统限制)。Observable
实例和线程切换,GC 压力大。val scope = CoroutineScope(Dispatchers.Default)
scope.launch {
val jobs = List(10_000) {
launch {
delay(100) // 非阻塞挂起,线程可被其他协程复用
// 执行任务
}
}
jobs.joinAll()
}
Dispatchers.Default
默认使用 CPU 核心数线程(如 8 线程),但 10,000 个协程可高效复用这些线程,总耗时仅约 100ms + 调度开销
。delay
)不阻塞线程,线程利用率接近 100%。假设需要先请求用户信息,再根据结果并发请求订单和消息列表,最后合并结果:
CompletableFuture<User> userFuture = CompletableFuture.supplyAsync(() -> getUser(), executor);
CompletableFuture<Order> orderFuture = userFuture.thenComposeAsync(user -> getOrder(user.id), executor);
CompletableFuture<List<Message>> messagesFuture = userFuture.thenComposeAsync(user -> getMessages(user.id), executor);
CompletableFuture.allOf(orderFuture, messagesFuture)
.thenAcceptAsync(v -> {
Order order = orderFuture.get();
List<Message> messages = messagesFuture.get();
showUI(order, messages);
}, uiExecutor);
thenComposeAsync
每次切换线程可能引入上下文开销。getUserObservable()
.flatMap(user ->
Observable.zip(
getOrderObservable(user.id).subscribeOn(Schedulers.io()),
getMessagesObservable(user.id).subscribeOn(Schedulers.io()),
(order, messages) -> Pair.create(order, messages)
)
)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(pair -> showUI(pair.first, pair.second));
flatMap
+ zip
的嵌套导致多次线程切换,且需手动管理 subscribeOn
和 observeOn
。Observable
对象,增加 GC 压力。lifecycleScope.launch { // Android 生命周期绑定
val user = async(Dispatchers.IO) { getUser() }.await()
val (order, messages) = coroutineScope {
val orderDeferred = async(Dispatchers.IO) { getOrder(user.id) }
val messagesDeferred = async(Dispatchers.IO) { getMessages(user.id) }
orderDeferred.await() to messagesDeferred.await()
}
withContext(Dispatchers.Main) { // 切回 UI 线程
showUI(order, messages)
}
}
coroutineScope
自动管理子协程生命周期。async
并发执行,复用 Dispatchers.IO
线程池,无额外线程切换开销。假设需要处理一个高频事件流(如传感器数据),进行过滤、转换和批量存储。
BlockingQueue<Data> queue = new LinkedBlockingQueue<>();
// 生产者线程池
Executors.newSingleThreadExecutor().submit(() -> {
while (true) {
Data data = readSensor();
queue.put(data); // 可能阻塞
}
});
// 消费者线程池
Executors.newFixedThreadPool(8).submit(() -> {
while (true) {
Data data = queue.take();
process(data); // 计算密集型任务
}
});
Flowable<Data> sensorFlow = Flowable.create(emitter -> {
while (!emitter.isCancelled()) {
Data data = readSensor();
emitter.onNext(data);
}
}, BackpressureStrategy.BUFFER);
sensorFlow
.onBackpressureBuffer()
.parallel(8) // 并行处理
.runOn(Schedulers.computation())
.map(data -> process(data))
.sequential()
.subscribe();
BUFFER
)可能导致内存溢出;parallel
操作符的线程管理复杂。val dataChannel = Channel<Data>(capacity = Channel.UNLIMITED) // 无界缓冲区
// 生产者协程
launch(Dispatchers.IO) {
while (true) {
val data = readSensor()
dataChannel.send(data)
}
}
// 消费者协程(启动 8 个并行处理)
repeat(8) {
launch(Dispatchers.Default) { // 使用 CPU 密集型调度器
for (data in dataChannel) {
process(data)
}
}
}
Channel
提供非阻塞的生产者-消费者模型,Dispatchers.Default
根据 CPU 核心数优化并行度。假设在 Android 低端设备(内存 1GB)中处理 1000 个并发 HTTP 请求:
Observable
和 Disposable
对象导致频繁 GC。val requests = (1..1000).map { i ->
lifecycleScope.async(Dispatchers.IO) {
api.fetchData(i) // 挂起函数,复用线程
}
}
requests.awaitAll()
Dispatchers.IO
动态调整线程池。场景 | 线程池 | RxJava | Kotlin 协程 |
---|---|---|---|
10,000 延迟任务 | ~15.6s (64线程) | ~15s + GC 抖动 | ~100ms |
链式网络请求 | 回调地狱,易遗漏错误 | 链式清晰,但内存占用高 | 同步写法,自动取消子任务 |
高频事件流处理 | 阻塞队列导致吞吐量瓶颈 | 背压管理复杂 | Channel 非阻塞,高吞吐 |
低内存设备并发 | OOM 崩溃 | 高频 GC | 内存占用低,无 OOM |
协程:
RxJava:
线程池:
-Dkotlinx.coroutines.debug
JVM 参数,日志中会显示协程 ID。CompositeDisposable
集中管理订阅。ThreadPoolExecutor
的 getActiveCount()
等方法实时监控负载。通过具体场景对比可见,Kotlin 协程在资源利用、代码可读性和性能上表现更优,尤其适合现代异步编程需求。