synchronized: A Simple Lock for Asynchronous Dart Code

Published on by Flutter News Hub

synchronized: A Simple Lock for Asynchronous Dart Code

In asynchronous Dart programming, it's crucial to prevent concurrent access to shared resources, which can lead to unexpected behavior and deadlocks. The synchronized package provides a straightforward lock mechanism to address this issue.

How It Works

The synchronized package implements basic lock functionality, ensuring that only one asynchronous task can access a shared resource at a time. It works by creating a queue and executing tasks one at a time.

Usage

To use the synchronized package, you can create a Lock object:

import 'package:synchronized/synchronized.dart';

final lock = Lock();

Then, you can use the synchronized() method to wrap your asynchronous task:

await lock.synchronized(() async {
  // Code that should be executed without concurrent access
});

Features

The synchronized package offers several useful features:

  • Non-reentrant locks: By default, locks are not reentrant, meaning a task cannot reacquire the same lock while it's already holding it.
  • Reentrant locks: Using Zones, you can create reentrant locks that allow tasks to reacquire the same lock multiple times.
  • Timeout support: You can specify a timeout for lock acquisition, after which an exception will be thrown.
  • Consistent behavior: The synchronized() method ensures that if a lock is unlocked, the next call to synchronized() will acquire the lock immediately.
  • Compatible with multiple platforms: synchronized works on web, mobile, and server environments.

Example

Consider the following code:

Future writeSlow(int value) async {
  await Future.delayed(Duration(milliseconds: 1));
  stdout.write(value);
}

Future write(List values) async {
  for (int value in values) {
    await writeSlow(value);
  }
}

Future write1234() async {
  await write([1, 2, 3, 4]);
}

void main() async {
  await lock.synchronized(write1234);
  await lock.synchronized(write1234);
}

Without the synchronized package, running write1234() twice would print the numbers out of order. However, using the synchronized lock, the output will be in the correct order (1234 1234).

Extension Method

You can also use the synchronized extension method:

class MyClass {
  Future myMethod() async =>
      await synchronized(() async { step1(); step2(); step3(); });
}

This allows you to lock on any object and perform synchronized operations.

Conclusion

The synchronized package provides a simple and effective way to prevent concurrent access to shared resources in Dart, ensuring the reliable execution of asynchronous tasks.

Flutter News Hub