Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Rust Dictionary

  1. Home
  2. Rust Dictionary
  3. Rc<RefCell<T>> / Arc<Mutex<T>>

Rc<RefCell<T>> / Arc<Mutex<T>>

Rc<RefCell<T>> is a pattern for multiple ownership with interior mutability in a single-threaded context. Arc<Mutex<T>> is a pattern for thread-safe multiple ownership with interior mutability in a multi-threaded context.

Syntax

use std::rc::Rc;
use std::cell::RefCell;
use std::sync::{Arc, Mutex};

// Single-threaded: multiple ownership + interior mutability
let shared = Rc::new(RefCell::new(value));
let clone = Rc::clone(&shared);
*shared.borrow_mut() = new_value;

// Multi-threaded: thread-safe multiple ownership + interior mutability
let shared = Arc::new(Mutex::new(value));
let clone = Arc::clone(&shared);
let mut guard = shared.lock().unwrap();
*guard = new_value;

Combination Overview

PatternThreadDescription
Rc<RefCell<T>>Single onlyReference-counted sharing with runtime borrow checking for mutability.
Arc<Mutex<T>>Multi-threadAtomic reference-counted sharing with exclusive access via Mutex.
Arc<RwLock<T>>Multi-threadMultiple threads can acquire a read-only lock simultaneously.

Sample Code

use std::rc::Rc;
use std::cell::RefCell;
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    // Rc<RefCell<T>>: append to a shared list in a single thread.
    let list = Rc::new(RefCell::new(vec![]));
    let list_a = Rc::clone(&list);
    let list_b = Rc::clone(&list);

    list_a.borrow_mut().push(1);
    list_b.borrow_mut().push(2);
    list.borrow_mut().push(3);
    println!("{:?}", list.borrow()); // [1, 2, 3]

    // Arc<Mutex<T>>: share a counter across multiple threads.
    let counter = Arc::new(Mutex::new(0));
    let handles: Vec<_> = (0..5).map(|_| {
        let cnt = Arc::clone(&counter);
        thread::spawn(move || {
            let mut n = cnt.lock().unwrap();
            *n += 1; // Acquire the Mutex lock before modifying the value.
        })
    }).collect();

    for h in handles {
        h.join().unwrap();
    }

    println!("counter: {}", *counter.lock().unwrap()); // counter: 5
}

Overview

In Rust, no single smart pointer can satisfy the need to mutate a value from multiple owners, so combining smart pointers is a common pattern. Rc<RefCell<T>> is the standard choice for single-threaded code, while Arc<Mutex<T>> is the standard choice for multi-threaded code.

To prevent forgotten lock releases, Rust's Mutex is designed so that the guard (MutexGuard) automatically releases the lock when it goes out of scope.

Locking multiple Mutexes in different orders can cause a deadlock. When multiple locks are needed, always design your code to acquire them in a consistent order.

If you find any errors or copyright issues, please .