Mutexes in JavaScript
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 asynchronous operations.
The Container
class holds a map of counters. Since we want to update it concurrently from multiple asynchronous operations, we add a Mutex
to synchronize access. Note that we’re using a third-party Mutex
implementation as JavaScript doesn’t have built-in mutexes.
The inc
method locks the mutex before accessing counters
and unlocks it at the end of the function using a try-finally block to ensure the mutex is always released.
In the main
function, we create a Container
instance and define an async function doIncrement
that increments a named counter in a loop.
We then run several async operations concurrently using Promise.all
. Note that they all access the same Container
, and two of them access the same counter.
After all operations finish, we print the final state of the counters.
Running the program shows that the counters are updated as expected:
This example demonstrates how to use mutexes to safely manage shared state in concurrent JavaScript code. While JavaScript doesn’t have built-in support for true parallelism due to its single-threaded nature, this pattern is useful for managing concurrent access in asynchronous operations, such as when dealing with multiple API requests or other I/O operations.
Next, we’ll look at implementing this same state management task using only asynchronous functions and message passing.