Rust Lesson 38 – Threads | Dataplexa

Threads in Rust

In this lesson, you will learn how to work with threads in Rust. Threads allow your program to execute multiple tasks concurrently, improving performance and responsiveness.

Rust provides safe and low-level access to operating system threads through its standard library.


What Is a Thread?

A thread is the smallest unit of execution within a process. Multiple threads can run independently while sharing the same memory space.

Threads are commonly used for:

  • Background processing
  • Handling multiple user requests
  • Parallel computations
  • Improving application performance

Creating Threads in Rust

Rust uses the std::thread module to create and manage threads.

use std::thread;

fn main() {
    thread::spawn(|| {
        println!("Hello from a thread!");
    });
}

This spawns a new thread that runs concurrently with the main thread.


Joining Threads

When a thread is created, Rust returns a JoinHandle. You can use it to wait for the thread to finish execution.

use std::thread;

fn main() {
    let handle = thread::spawn(|| {
        println!("Thread is running");
    });

    handle.join().unwrap();
}

Calling join() blocks the main thread until the spawned thread completes.


Main Thread vs Child Threads

The main thread is the starting point of the program. If the main thread exits, all child threads are terminated.

That is why joining threads is important.


Using the move Keyword

Threads often need to access variables from the main thread. Rust uses the move keyword to transfer ownership safely.

use std::thread;

fn main() {
    let data = String::from("Rust");

    let handle = thread::spawn(move || {
        println!("{}", data);
    });

    handle.join().unwrap();
}

Once ownership is moved, the original variable cannot be used again.


Multiple Threads

You can spawn multiple threads to perform parallel tasks.

use std::thread;

fn main() {
    let mut handles = vec![];

    for i in 0..5 {
        let handle = thread::spawn(move || {
            println!("Thread {}", i);
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }
}

Thread Scheduling

The operating system decides when each thread runs. The order of execution is not guaranteed.

This is why programs must not rely on execution order.


Thread Safety in Rust

Rust ensures thread safety using its type system.

  • Data races are prevented at compile time
  • Unsafe sharing is disallowed
  • Only safe patterns are permitted

If your code compiles, it is thread-safe.


Common Thread Use Cases

Threads are useful when:

  • Tasks can run independently
  • Workload can be divided
  • Blocking operations slow down execution

📝 Practice Exercises


Exercise 1

Create a thread that prints a number.

Exercise 2

Join a thread before program exit.

Exercise 3

Spawn three threads using a loop.

Exercise 4

Explain why joining threads is important.


✅ Practice Answers


Answer 1

thread::spawn(|| println!("1"));

Answer 2

let h = thread::spawn(|| {});
h.join().unwrap();

Answer 3

for i in 0..3 {
    thread::spawn(move || println!("{}", i));
}

Answer 4

Joining ensures that threads complete execution before the program exits.


What’s Next?

In the next lesson, you will learn about Channels in Rust, which allow safe communication between threads.