CodeBlanks Logo Icon CodeBlanks

Arc<T>

Learn thread-safe shared ownership with Arc<T>.

Arc<T>

Arc<T> (atomically reference counted) is the thread-safe version of Rc. It updates the counter with atomic operations; it's slightly slower but can be shared across threads:

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

let veri = Arc::new(vec![1, 2, 3]);
let v = Arc::clone(&veri);
let h = thread::spawn(move || v.iter().sum::<i32>());
println!("{}", h.join().unwrap());   // 6

Each thread takes its own Arc copy with move. The data is read-only; changing it needs Arc<Mutex<T>>.

Collecting results in order

The output order of threads is undetermined. Getting results with join both waits for them to finish and collects them in order:

let tutucular: Vec<_> = (1..=3)
    .map(|k| {
        let v = Arc::clone(&veri);
        thread::spawn(move || v.iter().sum::<i32>() * k)
    })
    .collect();
let sonuc: Vec<i32> = tutucular.into_iter().map(|h| h.join().unwrap()).collect();

Once all threads finish, their copies are dropped too and the counter is back to 1.

Practice Parallel sum

Share Arc::new(vec![1, 2, 3]). Start three threads for k = 1..=3, each computing sum * k, and collect the results in order with join. Print the result vector and the final Arc::strong_count value separated by a space.

Starter code

main.rs
use std::sync::Arc;
use std::thread;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
use std::sync::Arc;
use std::thread;

fn main() {
    let veri = Arc::new(vec![1, 2, 3]);
    let tutucular: Vec<_> = (1..=3)
        .map(|k| {
            let v = Arc::clone(&veri);
            thread::spawn(move || v.iter().sum::<i32>() * k)
        })
        .collect();
    let sonuc: Vec<i32> = tutucular.into_iter().map(|h| h.join().unwrap()).collect();
    println!("{:?} {}", sonuc, Arc::strong_count(&veri));
}

Expected output

[6, 12, 18] 1

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What happens if an <code>Rc</code> is used inside <code>thread::spawn(move || ..)</code>?

  • It works but is slow
  • Runtime panic
  • No problem
  • Compile error: Rc can't be sent safely between threads (not Send) Correct answer

Explanation: The compiler prevents data races at compile time with the Send/Sync traits.

2 Thread-safe sharing

Question
use std::sync::Arc;
let veri = ____::new(vec![1, 2, 3]);
Answer
use std::sync::Arc;
let veri = Arc::new(vec![1, 2, 3]);

Explanation: Sharing across threads needs Arc, with its atomic counter.

3 Type and property

Term Meaning
Rc<T> Single thread, sharing
Arc<T> Multiple threads, sharing
Box<T> Single owner
Arc<Mutex<T>> Shared mutation

All lessons in Intermediate