Mutex<T>は、共通リソースが複数のスレッド間で競合などが起きないようにしてくれます。::lockを実行することでMutexGuard<T>を取得できます。Tは安全に触りたい値のことで、MutextGuardがDerefを持ってることから楽に触る事ができます。
すべてのスレッドの処理が終わった後、再度Tを取得したい場合はメインスレッドで再度::lockし、MutexGuardに変換してから取得できます。
use std::sync::{Arc, Mutex};
use std::thread;
let values: Arc>> = Arc::new(Mutex::new(Vec::new()));
for i in 0..10 {
  let values = values.clone();
  thread::spawn(move || {
    let mut lock = values.lock().unwrap();
    lock.push(i);
  })
  .join()
  .unwrap();
}
let values = values.lock().unwrap();
assert_eq!(*values, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); あるスレッドのMutexGuardがスコープを抜けるまで他スレッドでは値を取得できない状態が続きます。なので以下のように書き換えると2つめの"foo"が出るまでに1秒の遅れが生まれます。
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
let values: Arc>> = Arc::new(Mutex::new(Vec::new()));
for i in 0..10 {
  let values = values.clone();
  thread::spawn(move || {
    let mut lock = values.lock().unwrap();
    
    println!("foo");
    
    lock.push(i);
    
    if i == 0 {
      thread::sleep(Duration::from_secs(1));
    }
  })
  .join()
  .unwrap();
}
let values = values.lock().unwrap();
assert_eq!(*values, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);