Rust Learning Path — Chapter 21. Rust's ownership and type systems extend naturally into concurrent programming. Many data-race mistakes that would become runtime bugs in other languages are rejected at compile time. This chapter covers threads, message passing, shared state, Mutex, Arc, and the Send/Sync marker traits.
1. Spawn a thread
use std::thread; fn main() { let handle = thread::spawn(|| { println!("worker running"); }); handle.join().unwrap(); }join() waits for the spawned thread to finish.
2. move captured values into a thread
let values = vec![1, 2, 3]; let handle = std::thread::spawn(move || { println!("{values:?}"); }); handle.join().unwrap();The move closure takes ownership so the spawned thread cannot outlive borrowed stack data.
3. Message passing with channels
use std::{sync::mpsc, thread}; fn main() { let (tx, rx) = mpsc::channel(); thread::spawn(move || { tx.send(String::from("done")).unwrap(); }); println!("{}", rx.recv().unwrap()); }4. Multiple producers
let (tx, rx) = std::sync::mpsc::channel(); let tx2 = tx.clone();Each sender can be moved into a different worker. The receiver consumes incoming messages.
5. Shared mutable state with Mutex
use std::sync::Mutex; let counter = Mutex::new(0); { let mut value = counter.lock().unwrap(); *value += 1; } println!("{:?}", counter);A mutex allows only one holder of the protected value at a time.
6. Share ownership with Arc
use std::{sync::{Arc, Mutex}, thread}; fn main() { let counter = Arc::new(Mutex::new(0)); let mut handles = vec![]; for _ in 0..4 { let counter = Arc::clone(&counter); handles.push(thread::spawn(move || { let mut value = counter.lock().unwrap(); *value += 1; })); } for handle in handles { handle.join().unwrap(); } println!("{}", *counter.lock().unwrap()); }7. Keep lock scopes small
Holding a lock while doing slow work reduces concurrency and can contribute to deadlocks. Acquire the guard as late as possible and release it as early as possible.
8. Send and Sync
Send indicates a type can safely transfer ownership to another thread. Sync indicates shared references can be used safely across threads. Most ordinary Rust types implement these automatically when their contents permit it.
9. Why Rc is not for threads
Rc uses non-atomic reference counting and is not Send. Use Arc when ownership must be shared across threads.
10. Thread pools
Creating one OS thread for every tiny job does not scale indefinitely. Production servers typically use a pool or an asynchronous runtime. Chapter 22 moves from OS-thread primitives into Tokio's async task model.
11. Panic handling
let result = thread::spawn(|| panic!("boom")).join(); if result.is_err() { eprintln!("worker failed"); }12. Common concurrency mistakes
- Holding mutex guards across expensive work.
- Using shared state when message passing would be simpler.
- Creating unbounded numbers of threads.
- Ignoring worker panics.
- Attempting to use Rc or RefCell across threads.
13. Mini lab: parallel counter
Create eight workers. Give each worker a vector slice or independent unit of work, send results back over a channel, and aggregate them on the main thread. Then implement a second version with Arc and compare the designs.
Key takeaways
Rust makes ownership part of concurrency design. Prefer the simplest model: isolated ownership first, messages when workers exchange data, and shared synchronization only when state truly must be shared.
Join the discussion
0 CommentsAsk questions, add context, or share what worked.
More from Melochip Editorial
Learn what Playwright testing is, why modern QA teams use it, how testers can get started, and the major types...
7 min read · Sep 19, 2026
Learn how Kubernetes Deployments and ReplicaSets work with practical YAML, scaling, self-healing, rolling upda...
7 min read · Sep 17, 2026
Learn Kubernetes security best practices with RBAC, Secrets, ServiceAccounts, Pod securityContext, NetworkPoli...
6 min read · Sep 17, 2026Related articles
Learn Linux from the ground up with simple explanations of the kernel, distributions, filesystem, commands, pe...
4 min read · Updated Oct 1, 2026
Learn what Playwright testing is, why modern QA teams use it, how testers can get started, and the major types...
7 min read · Sep 19, 2026
Learn how Kubernetes Deployments and ReplicaSets work with practical YAML, scaling, self-healing, rolling upda...
7 min read · Sep 17, 2026
Learn Kubernetes security best practices with RBAC, Secrets, ServiceAccounts, Pod securityContext, NetworkPoli...
6 min read · Sep 17, 2026Stay in the loop. Get new Melochip articles
Receive Melochip article updates when new articles are available. Explicit opt-in only.
No comments yet. Start the discussion.