tezvyn:

Rust's Arc<T>: Share Data Ownership Across Threads

AI-drafted, machine-checkedSource: doc.rust-lang.orgadvanced

Rust's `Arc<T>` lets multiple threads share ownership of heap data. It's a smart pointer that counts references atomically. Use it for shared caches or config. The footgun: `Arc` only makes sharing safe, not mutation—you still need a `Mutex` for that.

WHY IT EXISTS In concurrent programs, multiple threads often need to access the same piece of data. Rust's ownership model prevents this by default to avoid data races. Arc<T> solves this by providing a form of shared ownership that is safe to use across threads, automating memory management so the data is freed only when the last owner is gone.

THE MENTAL MODEL Think of an Arc<T> as a deed to a property that can be safely photocopied and given to multiple people (threads). Each copy is a valid claim of ownership. The property (the data T) is only demolished when the very last copy of the deed is destroyed. The "atomic" part means the copying and destroying process is managed in a way that prevents race conditions between threads.

HOW IT WORKS Arc<T> wraps a pointer to heap-allocated data and maintains a reference count. When you clone() an Arc, it doesn't clone the data; it just creates a new pointer to the same data and atomically increments the reference count. When an Arc goes out of scope, it atomically decrements the count. When the count reaches zero, the data is dropped. These atomic operations are slightly more expensive than the non-atomic ones in Rc<T>, but they are essential for thread safety.

WHEN TO USE IT Use Arc<T> when you need to share ownership of some data between multiple threads. Common cases include: a shared configuration struct read by many worker threads, a read-heavy cache, or a connection pool. If the compiler complains that a value has been moved but you need multiple threads to access it, Arc is often the solution.

WHEN NOT TO USE IT If your shared data is only ever used within a single thread, use Rc<T> to avoid the performance overhead of atomic operations. Arc does not protect against reference cycles; if two Arcs point to each other, they will create a memory leak. Use Weak<T> to break cycles. Also, if you can use static lifetimes and simple references (&T), prefer them over Arc for simplicity and performance.

ONE CANONICAL EXAMPLE The most common pattern is combining Arc with Mutex for shared, mutable state. An Arc<Mutex<Vec<i32>>> allows multiple threads to have owning references to a mutex-protected vector. Any thread can clone the Arc to get access, then lock the Mutex to safely read or write to the vector, ensuring no data races occur.

Read the original → doc.rust-lang.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.