Atomic reference counting

First of all, we use the Arc type. It is similar to the Rc type that we used in the previous chapter, in that it is a type providing reference counting. The difference between these two types is that Arc uses atomic operations to increment its counter. By being atomic, it is safe to be used by multiple threads while Rc cannot be safely used across threads (and the compiler prevents us from trying to do so). The standard library provides these two types so that you can choose the cost you want to pay. If you don't need to share a reference-counted value with multiple threads, choose Rc as it is more efficient than Arc. If you try to send an Rc to another thread, the compiler will trigger an error:

error[E0277]: the trait bound `std::rc::Rc<i32>: std::marker::Send` is not satisfied in `[closure@src/main.rs:6:19: 8:6 rc:std::rc::Rc<i32>]`
 --> src/main.rs:6:5
  |
6 |     thread::spawn(move || {
  |     ^^^^^^^^^^^^^ `std::rc::Rc<i32>` cannot be sent between threads safely
  |
  = help: within `[closure@src/main.rs:6:19: 8:6 rc:std::rc::Rc<i32>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<i32>`
  = note: required because it appears within the type `[closure@src/main.rs:6:19: 8:6 rc:std::rc::Rc<i32>]`
  = note: required by `std::thread::spawn`

In this case, you'll need to switch to an Arc. This error will make more sense when we see what the Send trait is.