Course contentsShow
← Rust
Lesson 176 of 1,9102. The Ownership ModelFree lesson

Fine-Grained Resource Locking

Partition memory into distinct regions protected by individual mutexes.

In this lesson, you will learn how to improve your program’s performance by partitioning memory into distinct regions, each protected by its own independent mutex.

The Problem: The "Global Bottleneck"

When you are managing a large resource—like a massive HashMap containing thousands of entries—using a single Mutex to guard the entire collection creates a bottleneck. Even if two threads want to modify completely different parts of the data, the second thread must wait for the first to finish because they are both fighting for the same lock. This is called "coarse-grained locking," and it often leads to threads idling while waiting for access.

The Solution: Fine-Grained Locking

Fine-grained locking solves this by breaking a large resource into smaller, independent pieces. Instead of wrapping the whole container in one lock, you partition the memory so that each "region" or "bucket" has its own Mutex.

Imagine a bank. If you had one lock for the entire building, only one person could transact at a time. If you provide a separate lock for each teller station, many people can be served simultaneously. We apply this same logic in Rust:

use std::sync::Mutex;

struct PartitionedData {
    // We split our data into 4 distinct regions
    region_a: Mutex<Vec<i32>>,
    region_b: Mutex<Vec<i32>>,
    region_c: Mutex<Vec<i32>>,
    region_d: Mutex<Vec<i32>>,
}

impl PartitionedData {
    fn add_to_a(&self, value: i32) {
        // Only locks region_a, leaving b, c, and d free for other threads
        let mut lock = self.region_a.lock().unwrap();
        lock.push(value);
    }
}

Why This Matters

By isolating sections of your data, you allow concurrent tasks to proceed in parallel as long as they operate on different partitions. You effectively reduce the amount of "contention" (the time threads spend waiting on each other).

When designing your own systems, look for logical boundaries within your data. If your resource can be split into independent zones, consider giving each zone its own Mutex. This keeps your memory usage efficient while drastically increasing the throughput of your concurrent applications.

Key Takeaway: By partitioning memory into smaller regions with their own dedicated mutexes, you reduce lock contention and allow multiple threads to access different parts of your data structure simultaneously.