How to Use Async Mutexes (tokio

:sync::Mutex vs std::sync::Mutex)

Use tokio::sync::Mutex for async code to avoid blocking the runtime, and std::sync::Mutex only for synchronous operations.

Use tokio::sync::Mutex inside async functions and std::sync::Mutex inside synchronous code to prevent deadlocks. Using std::sync::Mutex in an async context blocks the entire runtime thread, halting all other tasks until the lock is released.

use tokio::sync::Mutex;
use std::sync::Arc;

async fn update_counter(counter: Arc<Mutex<i32>>) {
    let mut num = counter.lock().await;
    *num += 1;
}

If you must use std::sync::Mutex in async code, wrap the blocking operation in tokio::task::spawn_blocking to offload it to a separate thread pool.