Bird
Raised Fist0
Rustprogramming~10 mins

Concurrency safety guarantees in Rust - Interactive Code Practice

Choose your learning style10 modes available
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to declare a thread-safe shared variable using Rust's atomic type.

Rust
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;

let counter = AtomicUsize::new([1]);
Drag options to blanks, or click blank then click option'
Atrue
B"0"
C0
DNone
Attempts:
3 left
💡 Hint
Common Mistakes
Using a string or boolean instead of a number for initialization.
2fill in blank
medium

Complete the code to spawn a thread that safely increments the atomic counter.

Rust
use std::sync::Arc;
use std::thread;

let counter = Arc::new(AtomicUsize::new(0));
let counter_clone = Arc::clone(&counter);

let handle = thread::spawn(move || {
    counter_clone.[1](1, Ordering::SeqCst);
});
Drag options to blanks, or click blank then click option'
Afetch_add
Bload
Cstore
Dswap
Attempts:
3 left
💡 Hint
Common Mistakes
Using load or store which do not perform atomic addition.
3fill in blank
hard

Fix the error in the code to safely share a mutable vector across threads using a Mutex.

Rust
use std::sync::{Arc, Mutex};
use std::thread;

let data = Arc::new(Mutex::new(vec![1, 2, 3]));
let data_clone = Arc::clone(&data);

let handle = thread::spawn(move || {
    let mut vec = data_clone.[1]().unwrap();
    vec.push(4);
});
Drag options to blanks, or click blank then click option'
Aunwrap
Bfetch_add
Cclone
Dlock
Attempts:
3 left
💡 Hint
Common Mistakes
Using unwrap() directly on the Arc or Mutex without locking.
4fill in blank
hard

Fill both blanks to create a thread-safe counter using Arc and Mutex.

Rust
use std::sync::{Arc, Mutex};
use std::thread;

let counter = Arc::new(Mutex::new([1]));
let counter_clone = Arc::clone(&counter);

let handle = thread::spawn(move || {
    let mut num = counter_clone.[2]().unwrap();
    *num += 1;
});
Drag options to blanks, or click blank then click option'
A0
Block
C1
Dclone
Attempts:
3 left
💡 Hint
Common Mistakes
Initializing with 1 or forgetting to lock the Mutex.
5fill in blank
hard

Fill all three blanks to create a thread-safe HashMap shared across threads with Arc and Mutex.

Rust
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;

let map = Arc::new(Mutex::new(HashMap::new()));
let map_clone = Arc::clone(&map);

let handle = thread::spawn(move || {
    let mut data = map_clone.[1]().unwrap();
    data.insert([2], [3]);
});
Drag options to blanks, or click blank then click option'
Alock
B"key"
C42
Dclone
Attempts:
3 left
💡 Hint
Common Mistakes
Forgetting to lock the Mutex or using incorrect key/value types.

Practice

(1/5)
1. Which Rust type is used to safely share ownership of data across multiple threads?
easy
A. Rc
B. Box
C. Arc
D. RefCell

Solution

  1. Step 1: Understand ownership sharing in concurrency

    In Rust, Arc (Atomic Reference Counted) allows multiple threads to share ownership safely.
  2. Step 2: Compare other options

    Box is for single ownership, Rc is not thread-safe, and RefCell is for interior mutability but not thread-safe.
  3. Final Answer:

    Arc -> Option C
  4. Quick Check:

    Safe shared ownership across threads = Arc [OK]
Hint: Arc is for thread-safe shared ownership [OK]
Common Mistakes:
  • Confusing Rc with Arc for multithreading
  • Using Box for shared ownership
  • Thinking RefCell is thread-safe
2. Which of the following is the correct syntax to create a Mutex protecting an integer value 5?
easy
A. let m = Mutex::new(5);
B. let m = Mutex(5);
C. let m = new Mutex(5);
D. let m = Mutex::create(5);

Solution

  1. Step 1: Recall Mutex creation syntax

    In Rust, you create a Mutex by calling Mutex::new(value).
  2. Step 2: Check each option

    Only let m = Mutex::new(5); uses the correct Mutex::new(5) syntax; others are invalid.
  3. Final Answer:

    let m = Mutex::new(5); -> Option A
  4. Quick Check:

    Mutex creation uses Mutex::new() [OK]
Hint: Use Mutex::new(value) to create a Mutex [OK]
Common Mistakes:
  • Omitting ::new when creating Mutex
  • Using constructor syntax like Mutex(5)
  • Confusing new() with create()
3. What will the following Rust code print?
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..3 {
        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!("{}", *counter.lock().unwrap());
}
medium
A. 0
B. 3
C. Compilation error
D. 1

Solution

  1. Step 1: Understand the code's concurrency logic

    The code creates 3 threads, each increments the shared counter by 1 inside a Mutex lock.
  2. Step 2: Calculate the final counter value

    Each thread adds 1, so total increments = 3. The final print shows 3.
  3. Final Answer:

    3 -> Option B
  4. Quick Check:

    3 threads incrementing counter = 3 [OK]
Hint: Count threads incrementing inside Mutex lock [OK]
Common Mistakes:
  • Ignoring Mutex lock and thinking of race conditions
  • Assuming only one thread runs
  • Expecting compilation error due to Arc usage
4. Identify the error in this Rust code snippet that tries to share a vector across threads:
use std::sync::Arc;
use std::thread;

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

    let handle = thread::spawn(move || {
        shared_numbers.push(4);
    });

    handle.join().unwrap();
}
medium
A. Vector is not thread-safe without Mutex or RwLock
B. Arc does not implement Send for Vec<T>
C. Cannot move vector into Arc
D. Missing clone of Arc before move

Solution

  1. Step 1: Examine the thread code

    The thread attempts to mutate the shared Arc<Vec<i32>> by calling push, but Arc provides only shared immutable access.
  2. Step 2: Recall requirements for mutable shared data

    To mutate data shared across threads, wrap it in Mutex or RwLock inside the Arc, e.g., Arc<Mutex<Vec<i32>>>.
  3. Step 3: Eliminate other options

    A: Vec can be moved into Arc. B: Arc<Vec<T>> implements Send/Sync for T: Sync. D: Clone not needed for single-thread move.
  4. Final Answer:

    Vector is not thread-safe without Mutex or RwLock -> Option A
  5. Quick Check:

    Mutable shared data needs Mutex or RwLock [OK]
Hint: Mutable shared data needs Mutex or RwLock [OK]
Common Mistakes:
  • Thinking Arc alone makes data mutable and safe
  • Confusing Send trait errors
  • Assuming clone is needed before move
5. You want to safely share and mutate a HashMap across multiple threads in Rust. Which combination of types ensures concurrency safety and allows mutation?
hard
A. Arc<RefCell<HashMap<String, i32>>>
B. Mutex<HashMap<String, i32>>
C. Rc<RefCell<HashMap<String, i32>>>
D. Arc<RwLock<HashMap<String, i32>>>

Solution

  1. Step 1: Identify thread-safe shared ownership

    To share data across threads, Arc is needed for atomic reference counting.
  2. Step 2: Choose synchronization primitive for mutation

    For mutable access, Mutex or RwLock can be used. RwLock allows multiple readers or one writer, improving concurrency.
  3. Step 3: Evaluate options

    Arc<RefCell<HashMap<String, i32>>> uses RefCell which is not Sync and thus not thread-safe. Arc<RwLock<HashMap<String, i32>>> uses RwLock which is suitable for read-heavy workloads with mutations. Rc<RefCell<HashMap<String, i32>>> uses Rc and RefCell, which are not thread-safe. Mutex<HashMap<String, i32>> lacks Arc, so no shared ownership across threads.
  4. Final Answer:

    Arc<RwLock<HashMap<String, i32>>> -> Option D
  5. Quick Check:

    Arc + RwLock = safe shared mutable access [OK]
Hint: Use Arc with RwLock for shared mutable access [OK]
Common Mistakes:
  • Using Rc or RefCell for multithreading
  • Omitting Arc for shared ownership
  • Choosing Mutex over RwLock without reason
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard