Send and Sync traits for safe concurrency guarantees

Marcus Chen Jan 2026
1 tab
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let data = Arc::new(Mutex::new(vec![1, 2, 3]));

    let handles: Vec<_> = (0..3)
        .map(|_| {
            let data_clone = Arc::clone(&data);
            thread::spawn(move || {
                data_clone.lock().unwrap().push(4);
            })
        })
        .collect();

    for h in handles {
        h.join().unwrap();
    }
}
1 file · rust Explain with highlit

Send means a type can be transferred across thread boundaries. Sync means a type can be shared between threads (&T is Send). Most types are Send + Sync; exceptions include Rc (not Send) and RefCell (not Sync). The compiler uses these marker traits to prevent data races at compile time. You rarely implement them manually; they're auto-derived when all fields are Send/Sync. For unsafe code that maintains invariants manually, you can implement them explicitly. Understanding Send and Sync is key to Rust's fearless concurrency: the type system prevents accidental data sharing. This is what makes Arc<Mutex<T>> safe: Arc is Send + Sync, Mutex ensures exclusive access.