Thread-Safe Arc(Atomically Reference Counted) = Shared pointer


                    data shared b/w threads (vec![1,2,3])
        refCount    1           2               n
                    /\          /\              /\
                    |           |               |
            Arc::clone()       Arc::clone()     Arc::clone()
            thread-1           thread-2         thread-n
            
Arc provides shared ownership of immutable data across multiple threads, With Arc::clone() reference count is incremented, and resource is freed when count=0
if you try to change data wrapped inside Arc, It gives compilation error

Features of Arc

1. Shared Ownership:
- Arc<T> provides shared ownership of a value of type T, allocated in the heap. clone() on Arc produces a new Arc instance, which points to the same allocation on the heap as the source Arc, while increasing a reference count.
- When the last Arc pointer to a given allocation is destroyed, the value stored in that allocation (inner value) is also dropped.
2. Mutable References:
- Shared references in Rust disallow mutation by default, and Arc is no exception: you cannot obtain a mutable reference to something inside an Arc
- If you need to mutate through an Arc, use Mutex, RwLock, or one of the Atomic types. Eg: Arc<Mutex<Value>> or Arc<RwLock<Value>>
3. Thread Safety:
- Unlike Rc <T>, Arc <T> uses atomic operations for its reference counting.
- The disadvantage is that atomic operations are more expensive than ordinary memory accesses. Consider using Rc<T> for lower overhead
4. Send, Sync Triats on Arc <T>:
Arc<T> will implement Send and Sync as long as the T implements Send and Sync

Changing data in Arc gives Compilation Error


use std::{sync::Arc, thread};
fn main() {
    let mut data = Arc::new(vec![1,2,3]);
    let mut handles = vec![];
    for i in 0..3 {
        let data_clone = Arc::clone(&data);

        //data_clone[2] = 1;        //Compilation Error

        let h = thread::spawn(move||{
            println!("{} {:?}",i, data_clone); 
        });
        handles.push(h);
    }
    for i in handles {
        i.join().unwrap();
    }
}
            

Rc<T> vs Arc<T>

RC<T> (Reference Counted Smart Pointer) Arc<T> (Atomically Reference Counted)
What Reference Counted Smart Pointer Same (Internally Uses atomic operations for reference counting)
Thread Safe No Yes
What Reference Counted Smart Pointer Same
Memory overhead Less More (Since it uses atomic operations Internally)
clone() Invoking clone produces a new pointer to the same allocation in the heap
When the last Rc pointer to a given allocation is destroyed, the value stored
in that allocation (often referred to as “inner value”) is also dropped
Same