WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Rust · Intermediate · question 36 of 100

What are the differences between Send and Sync traits, and when should you use each?

📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

The ‘Send‘ and ‘Sync‘ traits in Rust are used to indicate safe concurrency in multi-threaded programming.

‘Send‘ trait indicates that data can be safely transferred across threads, while ‘Sync‘ trait indicates that data can be safely shared between threads without causing data races.

Here are the differences between ‘Send‘ and ‘Sync‘ traits:

#### Send

The ‘Send‘ trait indicates that a type is safe to be transferred across threads. When a type implements the ‘Send‘ trait, it is guaranteed to be free of data races when passed between threads. For example, a ‘String‘ can be safely transferred between threads because it is immutable and doesn’t have any interior mutability. A mutex guard, on the other hand, cannot be transferred between threads because it represents a mutable state and could cause data races.

Here’s an example of using the ‘Send‘ trait:

    use std::thread;
    
    fn main() {
        let s = String::from("hello");
        
        let handle = thread::spawn(|| {
            println!("s: {}", s);
        });
        
        handle.join().unwrap();
    }

In this example, ‘String‘ implements ‘Send‘, so it can be safely passed to the closure spawned by the ‘thread::spawn‘ function.

#### Sync

The ‘Sync‘ trait indicates that a type is safe to be shared between threads. When a type implements the ‘Sync‘ trait, it is guaranteed to be free of data races when accessed from multiple threads simultaneously. For example, a ‘u32‘ can be safely shared between threads because it is immutable and has no interior mutability. A reference-counted type like ‘Arc<T>‘ can also be safely shared between threads because it ensures that the reference count is updated atomically.

Here’s an example of using the ‘Sync‘ trait:

    use std::sync::{Arc, Mutex};
    use std::thread;
    
    fn main() {
        let counter = Arc::new(Mutex::new(0));
        
        let mut handles = vec![];
        
        for _ in 0..10 {
            let counter = Arc::clone(&counter);
            let handle = thread::spawn(move || {
                let mut num = counter.lock().unwrap();
                *num += 1;
            });
            handles.push(handle);
        }
        
        for handle in handles {
            handle.join().unwrap();
        }
        
        println!("Result: {}", *counter.lock().unwrap());
    }

In this example, ‘Mutex<T>‘ implements ‘Sync‘, so it can be safely shared between threads. The ‘Arc<T>‘ type also implements ‘Sync‘, but it requires the ‘Mutex<T>‘ to synchronize access to the interior value.

So, when should you use each of these traits?

Use ‘Send‘ when you want to transfer ownership of data between threads, and use ‘Sync‘ when you want to share data between threads. In general, if a type is immutable and doesn’t have any interior mutability, it can implement both ‘Send‘ and ‘Sync‘. If a type is mutable, it can only implement ‘Sync‘, and requires synchronization to be accessed from multiple threads.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Rust interview — then scores it.
📞 Practice Rust — free 15 min
📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

All 100 Rust questions · All topics