美文网首页
Flutter -- 10.多线程

Flutter -- 10.多线程

作者: MissStitch丶 | 来源:发表于2021-11-16 14:23 被阅读0次

Dart中的多线程

  • Dart中多线程不仅仅是多线程,更像一个进程。拥有独立的内存空间,不存在资源抢夺的问题,因此也就没有了锁的概念了。

1.Isolate

  • 异步任务中数据是隔离的
  • 如果想要修改线程外数据,需要使用ReceivePort
    • 监听,port.listen((message) {})
    • 调用后senPort.send(data)后,会回调listen
      注意:此时listen回调后相当于添加一个主线程的异步任务。listen代码块任务,会最后执行
  • 既然开辟了线程及端口,完成后就需要释放它
  • 释放端口,port.close()
  • 释放线程对象
    • 1.方法后面加上async
    • 2.Isolate创建的时候加上await,等待Isolate创建
      注意:这里的await并不会阻塞主线程,因为Isolate开辟了子线程同时添加异步任务,这里的await是在子线程等待
    • 3.在需要杀死时调用,isolate.kill()
//1.验证多线程
testIsolate() {
  print('外部代码1');
  Isolate.spawn(func, 10);
  Isolate.spawn(func2, 10);
  Isolate.spawn(func, 10);
  Isolate.spawn(func2, 10);
  Isolate.spawn(func, 10);
  Isolate.spawn(func2, 10);

  sleep(Duration(seconds: 2));
  print('外部代码2');
}

//2.验证线程内和主线程下数据资源是不一样的
testIsolate2() {
  print('外部代码1');
  Isolate.spawn(func3, 100);
  sleep(Duration(seconds: 2));
  print('a = $a');
  print('外部代码2');
}

//3.修改线程外数据,使用SendPort与port.listen配合使用
testIsolate3() async {
  //创建一个port
  ReceivePort port = ReceivePort();
  print('外部代码1');
  /*
   * 这里的await并不会阻塞主线程,因为Isolate开辟了子线程同时添加异步任务,这里的await是在子线程等待。
   * 这里使用await为了给Isolate赋值,等待创建好的Isolate对象,保证在listen调用时,可以拿到Isolate对象。
   */
  Isolate isolate = await Isolate.spawn(func4, port.sendPort);
  port.listen((message) {
    //当sendPort发送数据后,会进入这个代码块,相当于在主线程添加了一个异步任务,因此在打印'外部代码2'后执行
    a = message;
    print('a修改为$a');
    isolate.kill();
    port.close();
  });
  //这里的sleep,为了验证当sendPort发送数据后,listen回调的代码块的执行顺序
  // sleep(Duration(seconds: 2));
  print('a = $a');
  print('外部代码2');
}

func(int count) => print('1');
func2(int count) => print('2');

int a = 10;
func3(int count) {
  a = count;
  print('func3中a = $a');
}

func4(SendPort sendPort) {
  sleep(Duration(seconds: 2));
  sendPort.send(100);
  print('send Completed');
}

2.compute

  • 基于Isolate的封装
  • 异步任务中数据也是隔离的,与Isolate一致
  • 可以接收异步任务返回的数据。
    注意:当接收返回的数据时,会阻塞主线程,因为返回值在主线程上接收的
  • 当然,这里也可以用then接收返回值,保证线程不被阻塞。
    注意:Isolate并不能使用该方式return返回值(传入的function无返回值,void),这是compute特有的封装(传入的function返回值为FutureOr<R>)
testCompute() async {
  print('外部代码1');
  //这里的value在主线程上接收的,因此这里会阻塞主线程
  int value = await compute(func5, 10);
  print(value); //15
  //异步任务中数据还是被隔离的,逻辑和Isolate一致。更改不了主线程下变量a的值
  print(a); //10
  print('外部代码2');
  // flutter: 外部代码1
  // flutter: count = 10
  // flutter: 15
  // flutter: 10
  // flutter: 外部代码2
}

//当然,这里也可以用then接收返回值,保证线程不被阻塞
testCompute2() {
  print('外部代码1');
  compute(func5, 10).then((value) {
    print(value);
    //主线程下的变量a被隔离着的
    print('a = $a');
  });
  print('外部代码2');
  // flutter: 外部代码1
  // flutter: 外部代码2
  // flutter: count = 10
  // flutter: 15
  // flutter: a = 10
}

int a = 10;
int func5(int count) {
  //尝试修改,查看是否影响线程外变量
  a = 100;
  print('count = $count');
  return count + 5;
}

3.异步多线程

  • 如何将一个异步任务,在子线程下执行
  • 在Future代码块里返回compute
//异步多线程
testAsyncThreads() {
  Future(()=>compute(funcCompute,1)).then((value) => print('Future任务1-$value'));
  Future(()=>compute(funcCompute,2)).then((value) => print('Future任务2-$value'));
  Future(()=>compute(funcCompute,3)).then((value) => print('Future任务3-$value'));
  Future(()=>compute(funcCompute,4)).then((value) => print('Future任务4-$value'));
  // flutter: Future任务1-1
  // flutter: Future任务4-4
  // flutter: Future任务3-3
  // flutter: Future任务2-2
}

funcCompute(int value)=>value;

此时,我们发现原本应该在事件队列中按顺序执行的任务,并发执行了
其实这里异步多线程的执行方式和多线程的执行方式一样

//多线程执行任务与异步多线程对比
testThreads() {
  compute(funcCompute,1).then((value) => print('compute任务1-$value'));
  compute(funcCompute,2).then((value) => print('compute任务2-$value'));
  compute(funcCompute,3).then((value) => print('compute任务3-$value'));
  compute(funcCompute,4).then((value) => print('compute任务4-$value'));
  // flutter: compute任务4-4
  // flutter: compute任务2-2
  // flutter: compute任务1-1
  // flutter: compute任务3-3
}

funcCompute(int value)=>value;

看到这里我们可以发现,异步完全没有必要,异步多线程其实就是多线程,在这里只是理解这一个概念。

相关文章

  • Flutter -- 10.多线程

    Dart中的多线程 Dart中多线程不仅仅是多线程,更像一个进程。拥有独立的内存空间,不存在资源抢夺的问题,因此也...

  • Chapter 10. 多线程

    阅读原文 Chapter 10. 多线程 10.1 多线程概述 基本概念:程序 - 进程 - 线程 程序(prog...

  • 2018-12-11

    10. HashMap在多线程环境下使用需要注意什么?为什么? 在多线程环境下,需要使用ConcurrentHas...

  • flutter记录

    Flutter技术和开发流程参考 dart Get Started dart pad 多线程 Flutter Ge...

  • 10.多线程

    知识点:一. 什么是线程: 进程是指运行中的应用程序,每一个进程都有自己独立的内存空间。一个应用程序可以同时启动多...

  • 开发十年,留下最完整的Java架构学习路线,学完年薪65W

    10. 解决临界资源问题之同步方法 11. 解决临界资源问题之ReentrantLock 12. 多线程讲解和理解...

  • 2020 下半年计划

    学习享学课堂 (包括Flutter 、小程序、kotlin等新知识) 具体计划:5月:搞清楚多线程:编写多线程系...

  • Flutter 异步编程

    由于Flutter是单线程的,所以java或原生的coder不要认为flutter的异步是多线程 了解java和j...

  • flutter 多线程

    https://juejin.im/post/5cc311695188252e83434aba 协程 async、...

  • 面试总结 优化

    1.Flutter的setState2.dart的多线程dart的多线程3.java线程池io密集型和Cpu密集型...

网友评论

      本文标题:Flutter -- 10.多线程

      本文链接:https://www.haomeiwen.com/subject/vtrqtrtx.html