liveBook · Manning

JoinHandle

As explained in Learn Rust in a Month of Lunches

JoinHandle is a Rust standard-library handle representing a spawned thread and allowing the program to wait for that thread to finish.

A JoinHandle is the handle returned by std::thread::spawn. It represents a spawned thread and lets the program wait until that thread finishes. Without waiting, main may finish while worker threads are still running. section 11.6.1 section 11.7

Wait for several threads

Store each handle, start all the threads, then join them afterward: let mut join_handles = vec![]; for _ in 0..10 { let handle = std::thread::spawn(|| { println!("I am printing something"); }); join_handles.push(handle); } for handle in join_handles { handle.join().unwrap(); } Calling join() makes the current code wait for that thread. Keeping handles in a vector allows all ten threads to start before the program waits for them. section 11.6.2

fn main() {
    let mut join_handles = vec![];           #1
    for _ in 0..10 {
        let handle = std::thread::spawn(|| {
            println!("I am printing something");
        });
        join_handles.push(handle);           #2
    }
    for handle in join_handles {             #3
        handle.join().unwrap();
    }
}

Browse the complete multi-thread example that collects JoinHandles and joins them after spawning all workers. section 11.6.2

A JoinHandle also exposes the lifetime boundary between the spawning code and its worker:

  • Calling join() inside the spawning loop waits before the next thread starts, so collecting handles first enables concurrent startup. section 11.6.2
  • Closures passed to spawn may need move so they own captured values; the compiler recommends it when borrowed data might outlive its scope. section 11.6.2

How Learn Rust in a Month of Lunches covers it

How deep it goes
Explains the spawn return type, join timing, handle collection, and closure lifetime constraints, while deferring newer non-static threads.
Examples
Uses ten printing threads, a vector of handles, join(), compiler feedback, and randomly ordered numbered output.
What it assumes
Assumes basic Rust closures and variables, while introducing thread completion, captured values, and the need for move.
What you can do after
Apply JoinHandle through std::thread::spawn, collect handles, and wait with join() after starting worker threads.
How it connects
Connects threads with spawn, join, closures, move, ownership, and lifetimes.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.