Flutter synchronized lock

涉及到多线程时,必须要考虑锁,数据同步。

找到资料:synchronized: https://pub.dev/packages/synchronized#-readme-tab-

最基本的一个应用:

  有一个变量a, 当多个线程访问时,必须保证同一时刻只有一个线程在读取/设置(类似于 C# 中的 lock(){} )。我们可以使用 synchronized 来处理就非常容易了。如:

_lock.synchronized(()async{
    //dealing with var a
    //...
});

这里有一个需要注意的地方是,这个同步程序块(程序函数)是异步的,举例下

先生成一个默认的工程,然后添加一个函数,函数的内容如下:

    debugPrint("${DateTime.now().toString()}$_bCounting");

    _lock.synchronized( ()async{//block 1
      _bCounting = !_bCounting;
      debugPrint("1:in lock. changed to: $_bCounting");

      _lock.synchronized( ()async{//block 2
        _bCounting = !_bCounting;
        debugPrint("2:in lock. changed to: $_bCounting");
      });
    });

添加2个变量

  bool _bCounting = false;
  var _lock = Lock();

可以添加一个按钮,然后点击调用上面的函数,结果如下:(按钮点击了2次)

2019-12-05 15:15:38.958 false
1:in lock. changed to: true
2:in lock. changed to: false

2019-12-05 15:15:45.535 false
1:in lock. changed to: true
2:in lock. changed to: false

似乎lock没有起作用。调用了2次,都进入了程序块。

实际问题出在: 2个程序块都没有等待完成,所以实际的情况是 block1 先完成,解锁,再顺利进入 block2

改一下程序,如下:block2 中加了 await

    debugPrint("${DateTime.now().toString()}$_bCounting");

    _lock.synchronized( ()async{
      _bCounting = !_bCounting;
      debugPrint("1:in lock. changed to: $_bCounting");

      await _lock.synchronized( ()async{ //added keyword "await"
        _bCounting = !_bCounting;
        debugPrint("2:in lock. changed to: $_bCounting");
      });
    });

运行结果如下:(按钮点击了2次)

2019-12-05 15:23:22.241 false
1:in lock. changed to: true

2019-12-05 15:23:24.196 true

现在每一次运行时,需要等待block2结束,而 block2 需要的资源需要等block1先结束,互相等待变成了死锁。

--END--

Ani
发布了83 篇原创文章 · 获赞 11 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/Ani/article/details/103405039