Dart 单线程说明
在 Java 中,默认为单线程执行,也就是通过main()
方法进行执行,按照顺序执行方式运行代码。
而 Dart 的单线程跟 Java 的完全不同,虽然都是单线程,但是 Dart 分为三个形式:
- 主线程
- 微任务队列
- 事件任务队列
主线程
跟 Java 一样,具有唯一性,也就是从main()
开始的线程。
微任务队列
里面包含众多微任务,主要是通过scheduleMicrotask
进行调度。
事件任务队列
里面包含众多事件任务,例如:I/O 事件任务、Timer 事件任务等。
Dart 单线程优先级
主线程 > 微任务队列 > 事件任务队列。
所以,在 Dart 单线程中,会优先执行完主线程,在执行主线程的过程中,若发现微任务或者事件任务,就会将他们放入相应的任务队列中,然后就会一个个执行完微任务队列里面的微任务,其次再去执行事件任务队列里面的事件任务。
但是,会有特殊情况,那就是可以在微任务里面产生事件任务,而在事件任务中也能产生微任务,那么在这种情况下,他们是怎么执行的?
微任务产生事件任务
刚刚说到,在执行完主线程后才会执行微任务队列,但是,在执行微任务的时候产生了事件任务,这时就会把事件任务加入到事件任务队列中,由于微任务队列的优先级比事件任务的高,所以,依旧会先执行完微任务队列再执行事件任务队列。
事件任务产生微任务
由于微任务队列的优先级比事件任务队列的高,所以在执行到事件任务队列的时候,微任务队列已经为空了,但是在事件任务队列中产生了微任务,所以,在每次执行完当前的事件任务的时候,都会去判断微任务队列是否为空:
- 微任务队列为空,继续执行下一个事件任务。
- 微任务队列不为空,转而执行微任务,微任务完成后,再次判断微任务队列是否为空,不为空才执行事件任务队列。
代码验证
特别说明
由于代码时直接运行在 flutter 项目中,所以在贴代码的时候会删除
import 'package:flutter/material.dart';
。runApp(MyApp());
相关代码。
只保留核心代码。
基础代码示例
首先,我们先演示最简洁的示例,也就是只有一个主线程、一个微任务、一个事件任务。
import 'dart:async';
//主线程
void main() {
print('main start!');
//微任务
scheduleMicrotask((){
print('微任务执行!');
});
//事件任务
Timer.run(() {
print('事件任务执行!');
});
print('main end!');
}
运行结果:
I/flutter: main start!
I/flutter: main end!
I/flutter: 微任务执行!
I/flutter: 事件任务执行!
延伸代码示例
下面演示的是在上面基础代码示例的基础上加上,微任务里面生成事件任务和在事件任务中生成微任务的情况。
import 'dart:async';
//主线程
void main() {
print('main start!');
//微任务
scheduleMicrotask((){
print('微任务 start!');
//子事件任务
Timer.run(() {
print('子事件任务执行!');
});
print('微任务 end!');
});
//事件任务
Timer.run(() {
print('事件任务 start!');
//子微任务
scheduleMicrotask((){
print('子微任务执行!');
});
print('事件任务 end!');
});
print('main end!');
}
运行结果:
I/flutter: main start!
I/flutter: main end!
I/flutter: 微任务 start!
I/flutter: 微任务 end!
I/flutter: 事件任务 start!
I/flutter: 子微任务执行!
I/flutter: 子事件任务执行!
阻塞问题
虽然按照上面的结果可以看出在单线程中,主线程、微任务队列、事件任务队列都是线性运行的,那么,假如我们在他们里面加入了阻塞操作,会不会依旧为线性运行?还是说,其实任务队列是并发的,只是微任务队列的优先级比事件任务队列的优先级高一点而已。
这里,我们通过加入sleep(Duration(seconds: 2));
代码模拟耗时操作。
import 'dart:async';
import 'dart:io';
//主线程
void main() {
print('main start!');
sleep(Duration(seconds: 2));
//微任务
scheduleMicrotask((){
print('微任务 start!');
sleep(Duration(seconds: 2));
//子事件任务
Timer.run(() {
print('子事件任务执行!');
sleep(Duration(seconds: 2));
});
print('微任务 end!');
});
//事件任务
Timer.run(() {
print('事件任务 start!');
sleep(Duration(seconds: 2));
//子微任务
scheduleMicrotask((){
print('子微任务执行!');
sleep(Duration(seconds: 2));
});
print('事件任务 end!');
});
print('main end!');
}
运行结果:
I/flutter: main start!
I/flutter: main end!
I/flutter: 微任务 start!
I/flutter: 微任务 end!
I/flutter: 事件任务 start!
I/flutter: 子微任务执行!
I/flutter: 子事件任务执行!
结果依旧一样,说明在 Dart 单线程中,主线程、微任务队列、事件任务队列是线性执行的!
猜你喜欢
- 面试官:如何提高Message的优先级
- 制作一个永远不会崩溃的App
- 自定义Gradle Plugin+字节码插桩
- 从手写ButterKnife到掌握注解、AnnotationProcessor
- 来,带你手写个性能检测工具
创作不易,你的点赞是我最大的支持。
这是我的公众号,关注获取第一信息!!欢迎关注支持下,谢谢!