通过本文阅读,可以了解Dart中的Isolate机制相关的用法、原理、使用场景。
目录
- 一、如何理解Dart语言的Isolate?
-
- [1. 什么是 Isolate?](#1. 什么是 Isolate?)
- [2. 为什么需要 Isolate?](#2. 为什么需要 Isolate?)
- [3. Isolate 的基本用法](#3. Isolate 的基本用法)
-
- [3.1 创建 Isolate](#3.1 创建 Isolate)
- [3.2 双向通信:使用SendPort 和 ReceivePort](#3.2 双向通信:使用SendPort 和 ReceivePort)
- [3.3 使用 Isolate.run(Dart 3.0+ 推荐方式)](#3.3 使用 Isolate.run(Dart 3.0+ 推荐方式))
- [4. 关键限制与注意事项](#4. 关键限制与注意事项)
- 5.典型应用场景
- 二、isolate的内部原理是什么?
-
- [1. 每个Isolate = 独立的执行环境](#1. 每个Isolate = 独立的执行环境)
- [2. Isolate与OS 线程的关系](#2. Isolate与OS 线程的关系)
- [3. Isolate 间通信:Port 机制](#3. Isolate 间通信:Port 机制)
- [4. 消息传递的底层实现](#4. 消息传递的底层实现)
- 三、Isolate运行在什么之上?
-
- [1. Isolate 与 OS 线程的关系(当前 Dart VM 行为)](#1. Isolate 与 OS 线程的关系(当前 Dart VM 行为))
- [2. 有没有可能多个 Isolate 共享一个 OS 线程?](#2. 有没有可能多个 Isolate 共享一个 OS 线程?)
- [3. 在JavaScript编译目标(如 dart2js)下呢?](#3. 在JavaScript编译目标(如 dart2js)下呢?)
- [四、 Dart VM 线程模型怎么理解?](#四、 Dart VM 线程模型怎么理解?)
-
- [1. 核心设计原则](#1. 核心设计原则)
- [2. Dart VM 线程模型图解(简化)](#2. Dart VM 线程模型图解(简化))
- [3. 关键组件详解](#3. 关键组件详解)
-
- [3.1 Isolate = 一个 OS 线程 + 独立运行时环境](#3.1 Isolate = 一个 OS 线程 + 独立运行时环境)
- [3.2 事件循环(Event Loop)------ 单线程内的"并发"](#3.2 事件循环(Event Loop)—— 单线程内的“并发”)
- [3.3 VM 内部辅助线程(用户不可见)](#3.3 VM 内部辅助线程(用户不可见))
- [4. Isolate 与 OS 线程的映射关系](#4. Isolate 与 OS 线程的映射关系)
- [5. 使用场景](#5. 使用场景)
- [6. 总结:Dart VM 线程模型要点](#6. 总结:Dart VM 线程模型要点)
一、如何理解Dart语言的Isolate?
Dart 的 Isolate 是 Dart 用于实现**并发(concurrency)和并行(parallelism)**的核心机制。由于 Dart 默认是单线程执行模型(基于事件循环),为了充分利用多核CPU或避免阻塞主线程(比如 UI 线程),Dart 引入了 Isolate 概念。
1. 什么是 Isolate?
- Isolate 是 Dart 中的独立运行单元,每个 isolate 都拥有自己的:
- 内存堆(heap)
- 垃圾回收器(GC)
- 事件循环(event loop)
- 不同 isolate 之间不能共享内存,这是与线程(thread)最大的区别。因此,isolate 之间通信必须通过消息传递(message passing)。
- 每个 Dart 程序至少有一个 isolate,称为主 isolate(main isolate)。
2. 为什么需要 Isolate?
- 避免阻塞主 isolate(特别是 Flutter 应用中的 UI 线程)
例如:执行耗时计算、文件 I/O、网络请求等。 - 利用多核 CPU 并行处理任务
多个 isolate 可以在不同 CPU 核心上同时运行。 - 提高程序响应性和性能
3. Isolate 的基本用法
3.1 创建 Isolate
dart
import 'dart:isolate';
void main() async {
// 创建一个 ReceivePort 用于接收子 isolate 发来的消息
final receivePort = ReceivePort();
// 启动新 isolate,传入入口函数和初始消息通道
await Isolate.spawn(entryPoint, receivePort.sendPort);
// 监听子 isolate 的返回消息
receivePort.listen((message) {
print('Main isolate received: $message');
receivePort.close();
});
}
// 子 isolate 的入口函数(必须是顶级函数或静态方法)
void entryPoint(SendPort sendPort) {
// 执行一些工作
final result = heavyComputation();
// 通过 sendPort 发送结果回主 isolate
sendPort.send(result);
}
int heavyComputation() {
// 模拟耗时操作
int sum = 0;
for (int i = 0; i < 100000000; i++) {
sum += i;
}
return sum;
}
3.2 双向通信:使用SendPort 和 ReceivePort
- SendPort:用于发送消息(可跨 isolate 传递)
- ReceivePort:用于监听消息(只能在创建它的 isolate 中使用)
注意:你不能直接把 ReceivePort 传给另一个 isolate,但可以把它的 sendPort 传过去。
3.3 使用 Isolate.run(Dart 3.0+ 推荐方式)
Dart 3 引入了更简洁的 Isolate.run,自动管理 isolate 生命周期:
dart
import 'dart:isolate';
void main() async {
final result = await Isolate.run(() {
// 在新 isolate 中执行
return heavyComputation();
});
print('Result: $result');
}
优点:代码简洁,自动关闭 isolate,适合"一次性的"任务。
4. 关键限制与注意事项

5.典型应用场景
- 图像/视频处理
- 加密/解密
- 大数据计算(如统计、排序)
- 解析大型 JSON/XML 文件
- 游戏 AI 计算(在后台进行)
总结
Isolate 是 Dart 实现安全并发的核心机制:通过隔离内存 + 消息传递,既保证了线程安全,又支持并行计算。
二、isolate的内部原理是什么?
Isolate 是 Dart 虚拟机(VM)内部的并发单元,其通信发生在同一进程内,不涉及网络协议栈。
Isolate 之间的消息传递虽然语义上类似"发送/接收",但底层使用的是高效的内存拷贝 + 消息队列,而非 TCP/UDP 或 Unix Domain Socket。
1. 每个Isolate = 独立的执行环境
在 Dart VM 中,每个 Isolate 包含:

这种设计避免了传统多线程中的竞态条件(race condition) 和 死锁(deadlock),因为没有共享状态。
2. Isolate与OS 线程的关系
- 一个 Isolate 通常绑定到一个 OS 线程(由 Dart VM 的线程池管理)。
- 但 Dart VM 可以在多个 OS 线程之间调度 isolate(尤其是在支持并发 GC 的版本中)。
- 多个 Isolate 可以并行运行在多个 CPU 核心上,因为它们映射到不同的 OS 线程。
3. Isolate 间通信:Port 机制
Dart 使用 Port(端口) 实现 isolate 间通信:
- SendPort:轻量级句柄,可跨 isolate 传递,用于发送消息。
- ReceivePort:本地监听器,绑定到当前 isolate 的消息队列。
底层机制:
- 当你调用 sendPort.send(data) 时:
- Dart VM 序列化data(通过 snapshotting / object graph copying)。
- 将序列化后的数据放入目标 isolate 的消息队列(message queue)。
- 目标 isolate 的事件循环在下一次 tick 中反序列化并触发 listener。
数据是深拷贝(deep copy),不是引用传递。因此不能传函数、闭包、不可序列化对象(如File、Socket 实例等)。
4. 消息传递的底层实现
在 Dart VM 源码中(C++ 层):
- 每个 Isolate 有一个 Message Handler 和 Message Queue。
- 消息通过 Message::New() 创建,并通过 MessageHandler::PostMessage() 投递。
- 投递过程使用线程安全的队列(如 Mutex + Condition Variable),确保线程安全。
- 不涉及系统调用如 socket()、send()、recv(),完全是用户态内存操作。
三、Isolate运行在什么之上?
在 Dart 的标准实现(Dart VM)中,每一个 Isolate 最终都运行在一个操作系统线程(OS thread)上。
它不能"运行在别的东西上"------比如协程、绿色线程、或直接跑在 CPU 上。
严格来说:
Isolate 总是映射到 OS 线程(由 Dart VM 管理),不存在"除了线程之外的运行载体"。
1. Isolate 与 OS 线程的关系(当前 Dart VM 行为)
- 每个 Isolate 在启动时,Dart VM 会为其分配一个 专属的 OS 线程(从内部线程池中获取)。
- 这个线程:
- 运行该 isolate 的事件循环(event loop)
- 执行所有同步和异步代码
- 执行 GC(在较新版本中,GC 可能使用辅助线程,但 mutator 线程仍是 isolate 主线程)
- 多个 Isolate → 多个 OS 线程 → 可并行利用多核 CPU
这就是为什么 Isolate.spawn() 能真正实现并行计算(parallelism),而不仅仅是并发(concurrency)。
2. 有没有可能多个 Isolate 共享一个 OS 线程?
- 技术上可行,但 Dart VM 默认不这么做。
- 如果强制让多个 isolate 共享一个线程,它们就无法并行执行(变成协作式多任务),失去了 isolate 的主要优势之一。
- Dart 团队明确设计 isolate 为重量级并发单元(相比 async/future),用于 CPU 并行。
3. 在JavaScript编译目标(如 dart2js)下呢?
- 当 Dart 代码被编译成 JavaScript(运行在浏览器或 Node.js 中),Isolate 无法真正实现。
- 因为 JS 是单线程 + Web Worker 模型。
- 此时:
- dart:isolate 库不可用(会报错)
- Flutter Web 也不支持 Isolate(需用 Web Worker 替代)
- 所以 Isolate 是 Dart VM 特有的能力,依赖原生运行时。
四、 Dart VM 线程模型怎么理解?
Dart VM(Dart 虚拟机)的线程模型是其高性能、响应式和并发能力的核心基础。它采用了一种混合线程架构,结合了 Isolate(隔离执行单元) 与 事件驱动单线程模型(Event Loop),既支持真正的并行(parallelism),又保持了内存安全和编程简洁性。
下面我们从整体架构到细节逐层解析 Dart VM 的线程模型。
1. 核心设计原则
- 无共享内存并发
→ 不同 Isolate 之间不能共享对象,避免竞态条件。 - 单 Isolate 内单线程执行
→ 每个 Isolate 只有一个"mutator thread"(执行 Dart 代码的线程),所有同步/异步代码都在这个线程上运行(通过事件循环调度)。 - Isolate 间通过消息传递通信
→ 使用 SendPort / ReceivePort,底层是深拷贝 + 消息队列。 - VM 内部可使用辅助线程
→ 如 GC、JIT 编译、I/O 等由 VM 在后台线程处理,但不暴露给 Dart 用户代码。
2. Dart VM 线程模型图解(简化)

3. 关键组件详解
3.1 Isolate = 一个 OS 线程 + 独立运行时环境
- 每个 Isolate 启动时,Dart VM 会为其分配:
- 一个专属的 OS 线程(称为 mutator thread)
- 独立的 堆内存(heap)
- 独立的 垃圾回收器(GC)状态
- 独立的 事件循环(event loop)
- 所有 Dart 用户代码(包括 async 函数)都在这个线程上顺序执行(非抢占式)。
- 因此:单个 Isolate 内不存在线程安全问题(因为没有并发执行)。
这就是为什么在 Flutter 中,UI 构建和逻辑必须快速完成------否则会阻塞整个 Isolate 的事件循环,导致 UI 卡顿。
3.2 事件循环(Event Loop)------ 单线程内的"并发"
每个 Isolate 内部有一个 事件循环,用于调度:
- Future.then()
- async / await
- Timer
- 微任务(Microtasks):如 scheduleMicrotask
- I/O 事件(通过 VM 的 I/O 服务线程回调)
注意:这些"异步"操作不会创建新线程,只是将任务切片插入事件队列,由同一个 OS 线程依次执行。
3.3 VM 内部辅助线程(用户不可见)
Dart VM 在后台启动若干 OS 线程来提升性能,但这些线程不运行用户 Dart 代码:

例如:当你调用 File.readAsString(),实际 I/O 操作由 I/O 线程完成,完成后通过消息通知 mutator 线程执行回调。
4. Isolate 与 OS 线程的映射关系
Dart 不提供线程池的api,如果需要复用 isolate,需自行实现(如维护一个 isolate 池)。

5. 使用场景

6. 总结:Dart VM 线程模型要点
- 每个 Isolate = 1 个 OS 线程 + 独立内存 + 事件循环
- Isolate 内部是单线程执行,靠事件循环实现"伪并发"
- Isolate 之间完全隔离,通信靠消息传递(深拷贝)
- VM 内部使用多线程优化 GC、I/O、编译,但对用户透明
- 真正并行靠多个 Isolate,而非 async/await
这种模型使得 Dart 在Flutter(UI 响应性) 和 服务端(高并发 I/O) 场景下都能表现优异。