🎓 A1Learner
🔍

Rust Mutex Basics

A Mutex is a lock on a value, like the one microphone at a meeting. Only the thread holding it may touch the value.

Wrap the value in a Mutex

Mutex::new wraps a value in a lock. The type is Mutex<i32> now, not i32:

let m = Mutex::new(5);

The type will not let you skip the lock

There is no direct road to the number inside. The compiler refuses to print a Mutex as if it were a number:

let m = Mutex::new(5_i32);
println!("{m}");
// error E0277: Mutex<i32> doesn't implement std::fmt::Display

Lock it to change it

lock() waits until the lock is free, then hands you a guard. The binding stays immutable — the change happens through the guard, with * for the plain value:

let mut num = m.lock().unwrap();
*num = 6;
println!("now = {}", *num);

try_lock answers at once, without waiting

Sometimes waiting is the worst option. try_lock either takes the lock immediately or reports that it is held — even when the holder is this very thread:

let m = Mutex::new(5);
let _held = m.lock().unwrap();
println!("second try got the lock = {}", m.try_lock().is_ok());

A panicking holder poisons the lock

lock() returns a Result. If a holder panics while holding the lock, the lock is poisoned — and the next lock() call is an Err:

let _ = std::panic::catch_unwind(|| {
    let _g = m.lock().unwrap();
    panic!("the holder panics");
});
println!("next lock is Err = {}", m.lock().is_err());

Example

use std::sync::Mutex;
fn main() {
    let m = Mutex::new(5);
    {
        let mut num = m.lock().unwrap();
        *num = 6;
    }
    println!("m = {}", *m.lock().unwrap());
}

Key points

  • A Mutex guards one value: the lock is the only way in, and one thread holds it at a time.
  • In Rust the guard is a value — when it goes, the lock goes.
  • Mutex is short for mutual exclusion.

In this example, m is a Mutex holding the number 5. Inside the block, m.lock() takes the lock and unwrap() takes the guard out of the Ok. *num = 6 changes the value through the guard. The block then ends, the guard is dropped, and the lock frees itself — no unlock line exists. The last line locks once more and prints the value through the new guard: m = 6.

Note

In many languages you lock and unlock by hand, and forgetting to unlock is a classic bug.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

When is a Mutex unlocked in Rust?