Isolate 线程(进程)
isolate开辟的线程是随机并发的
代码语言:javascript复制isolateDemo() {
Isolate.spawn(func1, 10);
Isolate.spawn(func2, 10);
Isolate.spawn(func1, 10);
Isolate.spawn(func2, 10);
Isolate.spawn(func1, 10);
Isolate.spawn(func2, 10);
}
func1(int num) {
print('任务1');
}
func2(int num) {
print('任务2');
}
输入结果:
I/flutter ( 1559): 任务1
I/flutter ( 1559): 任务2
I/flutter ( 1559): 任务2
I/flutter ( 1559): 任务1
I/flutter ( 1559): 任务1
I/flutter ( 1559): 任务2
isolate开辟的线程是在新的进程上开辟的,拥有完全独立的内存空间
代码语言:javascript复制int count = 10;
isolateDemo() {
Isolate.spawn(func, 100);
sleep(const Duration(seconds: 5));//睡眠5s,等待子线程执行完
print('count = $count');
}
func(int num) {
count = num;
print('isolate.count = $count');
}
I/flutter ( 1559): isolate.count = 100
I/flutter ( 1559): count = 10
从结果上看,子线程修改完全局变量,主线程的count还是原来的值。要想从子线程同步执行结果,dart提供了接口port,监听port回调来获得子线程的回调结果。
代码语言:javascript复制int count = 10;
isolateDemo() async{
ReceivePort receive = ReceivePort();
Isolate iso = await Isolate.spawn(func, receive.sendPort);
receive.listen((message) {
count = message;
print('接收到 新的count = $count');
receive.close();//用完需关闭port
iso.kill();
});
sleep(const Duration(seconds: 5));
print('count = $count');
}
func(SendPort sendPort) {
count = 100;
sendPort.send(count);
print('isolate.count = $count');
}
I/flutter ( 1559): isolate.count = 100
I/flutter ( 1559): count = 10
I/flutter ( 1559): 接收到 新的count = 100
compute 与 isolate的区别,compute是是在isolate的上再封装了一层。compute有返回值直接就可以接受。
代码语言:javascript复制const ComputeImpl compute = isolates.compute;
代码语言:javascript复制computeDemo() async{
print('代码1');
int num = await compute(func3,100) as int;
print('num = $num');
print('代码2');
}
int func3(int count){
sleep(Duration(seconds: 5));
return 1000;
}
I/flutter ( 1559): 外部代码1
I/flutter ( 1559): num= 1000
I/flutter ( 1559): 外部代码2
而且,await会堵塞下面的代码,直到compute执行完才继续往下执行。如果是isolate.spawn直接开辟的线程是不会堵塞往下的代码。
无论是compute 还是 isolate都必须在asyn函数内使用。
事件任务与微任务
在每一次事件循环中,Dart
总是先去第一个microtask queue
中查询是否有可执行的任务,如果没有,才会处理后续的event queue
的流程
void futureDemo(){
Future f1 = Future(() => null);
Future f2 = Future(() => debugPrint('1'));
f2.then((value) => debugPrint('4'));
f1.then((value) {
debugPrint('6');
}).then((value) => debugPrint('8'));
Future(() => debugPrint('2'));
scheduleMicrotask(() {debugPrint('3');});
debugPrint('5');
//5 3 6 1 4 2
}
结果:
I/flutter ( 1559): 5
I/flutter ( 1559): 3
I/flutter ( 1559): 6
I/flutter ( 1559): 8
I/flutter ( 1559): 1
I/flutter ( 1559): 4
I/flutter ( 1559): 2
代码段执行顺序:主线程 - 队列(Future) - 微任务(scheduleMicrotask)
future和then分开写还是一起写,都是同一行执行语句。future执行完,马上就会执行相应的then、whenComplete
代码语言:javascript复制void futureDemo(){
Future f1 = Future(() => null);
f1.then((value) {
debugPrint('6');
scheduleMicrotask(() {debugPrint('7');});//f1、then、whenComplete同属一执行语句。每个事件任务执行完会再去轮询微任务
}).then((value) => debugPrint('8')).whenComplete(() => debugPrint('9'));
Future f2 = Future(() => debugPrint('1'));
f2.then((value) => debugPrint('4'));
Future(() => debugPrint('2'));
scheduleMicrotask(() {debugPrint('3');});//微任务
debugPrint('5');
//5 3 6 8 9 7 6 1 4 2
}
I/flutter ( 1559): 5
I/flutter ( 1559): 3
I/flutter ( 1559): 6
I/flutter ( 1559): 8
I/flutter ( 1559): 9
I/flutter ( 1559): 7
I/flutter ( 1559): 1