Mutexes in Dart

In the previous example we saw how to manage simple counter state using atomic operations. For more complex state we can use a mutex to safely access data across multiple isolates.

import 'dart:async';
import 'dart:isolate';

class Container {
  final Map<String, int> _counters = {};
  final _lock = Lock();

  Future<void> inc(String name) async {
    await _lock.synchronized(() {
      _counters[name] = (_counters[name] ?? 0) + 1;
    });
  }

  Map<String, int> get counters => Map.unmodifiable(_counters);
}

void main() async {
  final container = Container();
  container._counters['a'] = 0;
  container._counters['b'] = 0;

  final completer = Completer<void>();
  var completedCount = 0;

  void doIncrement(String name, int n) async {
    for (var i = 0; i < n; i++) {
      await container.inc(name);
    }
    completedCount++;
    if (completedCount == 3) completer.complete();
  }

  // Run several isolates concurrently
  Isolate.spawn(doIncrement, ['a', 10000]);
  Isolate.spawn(doIncrement, ['a', 10000]);
  Isolate.spawn(doIncrement, ['b', 10000]);

  // Wait for the isolates to finish
  await completer.future;
  print(container.counters);
}

In this Dart version, we use a Lock from the synchronized package to implement mutual exclusion. The Container class holds a map of counters, and we use the Lock to synchronize access to this map.

The inc method is now asynchronous, as it needs to acquire the lock before updating the counter.

Instead of goroutines, we use Dart’s Isolates for concurrent execution. The doIncrement function is spawned in separate isolates to increment the counters.

We use a Completer to wait for all isolates to finish their work before printing the final counter values.

Note that the zero value of a Lock is usable as-is, so no initialization is required.

Running the program shows that the counters are updated as expected:

$ dart run mutexes.dart
{a: 20000, b: 10000}

Next, we’ll look at implementing this same state management task using only isolates and ports for communication.