前言:Isolate译为隔离,区别于java的线程,由于内存是隔离的,更类似进程。sync和await则是在Isolate中将任务添加到事件队列,await中的任务和await外的任务是并发的,但await中的任务之间是根据队列顺序执行的详见。
使用:
SendPort newSendPort;
static int num = 0;
//该方法内部运行在MainIsolate
Future<void> test() async {
//创建接收端口
ReceivePort mainReceivePort = ReceivePort();
//获取发送端口(提供给NewIsolate用作发送信息)
SendPort mainSendPort = mainReceivePort.sendPort;
//创建新Isolate,第1个参数为方法名,第2个参数为入参
await Isolate.spawn(creatNewIsolate, mainSendPort);
//监听来自NewIsolate的消息
mainReceivePort.listen((message) {
if(message is SendPort){
newSendPort = message;
print("收到NewIsolate的发送端口");
}else if(message is String){
print("MainIsolate收到消息:" + message);
print("MainIsolate num = $num");
}
});
}
//该方法内部运行在NewIsolate
static Future<void> creatNewIsolate(SendPort mainSendPort) {
//创建接收端口
ReceivePort newReceivePort = ReceivePort();
//获取发送端口
SendPort newSendProt = newReceivePort.sendPort;
//发送消息
mainSendPort.send(newSendProt);
//监听来自MainIsolate的消息
newReceivePort.listen((message) {
print("NewIsolate收到消息:" + message);
num++;
mainSendPort.send("$num");
});
}
分析:
1、Isolate间内存是相互隔离的,如上述在MainIsolate中num始终为0,而在NewIsolate中则为累加后的值。
2、Isolate间是通过端口通讯的,MainIsolate和NewIsolate相互持有对方的发送端口,通过该端口相互发送消息
3、支持的消息类型如下:详见
4、creatNewIsolate需要是静态函数或顶部函数
使用compute简化
由于Isolate写起来还是比较繁琐的,flutter封装了compute简化代码。
void testCompute() async{
String result = await compute(createCompute, "这是入参");
print("结果:$result");
}
//该方法内部运行在新的Isolate
static String createCompute(String st) {
print(st);
sleep(Duration(seconds: 5),);
return "这是结果";
}
使用LoadBalancer优化
虽然compute简化了代码,但有不足的地方如每次compite则会新创建Isolate,那么我们可以采用LoadBalancer来优化(类似线程池)。
1、pubspec.yaml 中添加 isolate 的依赖
isolate: ^2.0.2
2、使用例子
void testLoadBalancer() async{
//创建LoadBalancer,第1个参数为Isolate个数
Future<LoadBalancer> loadBalancer = LoadBalancer.create(4, IsolateRunner.spawn);
//使用LoadBlancer
String result = await (await loadBalancer).run(useLoadBalancer, "这是入参");
print("结果:$result");
}
//该方法内部运行在非主Isolate
static String useLoadBalancer(String st) {
print(st);
sleep(Duration(seconds: 15),);
return "这是结果";
}