TopDev

ThreadLocal là gì và dùng để làm gì?

minhu 📖 4 phút đọc

Trong lập trình đa luồng (multithreading), việc chia sẻ dữ liệu giữa các thread thường dẫn đến vấn đề tranh chấp tài nguyên (race condition), hoặc cần đồng bộ (synchronized) phức tạp. Đây là lúc ThreadLocal phát huy sức mạnh: giúp mỗi thread có vùng dữ liệu riêng biệt, không bị ảnh hưởng bởi các thread khác.

Vậy ThreadLocal là gì? ThreadLocal dùng để làm gì? Bài viết này sẽ giúp bạn hiểu rõ bản chất, cách sử dụng và khi nào nên dùng ThreadLocal trong Java hoặc các ngôn ngữ hỗ trợ tính năng tương tự.



✅ ThreadLocal là gì?#

ThreadLocal là một lớp trong Java (java.lang.ThreadLocal) cho phép bạn lưu trữ dữ liệu riêng biệt cho từng thread. Mỗi thread khi truy cập vào một biến ThreadLocal sẽ nhận được bản sao riêng, độc lập với các thread khác.

Nói cách khác:

  • Không cần dùng synchronized.

  • Không bị race condition.

  • Mỗi thread có “biến toàn cục riêng” của nó.

🧠 Cách hiểu đơn giản:#

Giống như mỗi nhân viên trong công ty có một ngăn tủ cá nhân (ThreadLocal) – cùng một loại tủ nhưng không ai thấy được đồ của người khác.



🧪 Cách sử dụng ThreadLocal trong Java#

` public class Demo { private static ThreadLocal threadLocal = ThreadLocal.withInitial(() -> 0);

public static void main(String[] args) {
    Runnable task = () -> {
        threadLocal.set((int) (Math.random() * 100));
        System.out.println(Thread.currentThread().getName() + " => " + threadLocal.get());
    };

    new Thread(task).start();
    new Thread(task).start();
    new Thread(task).start();
}

} `

📌 Giải thích:#

  • Mỗi thread sẽ set giá trị riêng cho biến threadLocal.

  • threadLocal.get() trả về đúng giá trị mà thread đó đã set.

  • Các thread không chia sẻ giá trị của nhau.



🎯 ThreadLocal dùng để làm gì?#

1. Giữ thông tin người dùng (user context)#

Khi xây dựng web service đa luồng (VD: Spring Boot), bạn có thể dùng ThreadLocal để lưu thông tin người dùng đăng nhập trong suốt quá trình xử lý request.

` public class UserContext { private static ThreadLocal currentUser = new ThreadLocal<>();

public static void set(User user) {
    currentUser.set(user);
}

public static User get() {
    return currentUser.get();
}

} `

2. Lưu phiên bản formatter riêng cho mỗi thread#

Một ví dụ phổ biến khác là với SimpleDateFormat, vốn không thread-safe. ThreadLocal giúp mỗi thread dùng formatter riêng:

private static final ThreadLocal<SimpleDateFormat> formatter = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

3. Giảm thiểu synchronized#

ThreadLocal tránh việc phải đồng bộ dữ liệu bằng synchronized, từ đó tăng hiệu năng.

4. Trong framework/web server#

Nhiều framework Java như Spring, Hibernate, hoặc web server như Tomcat sử dụng ThreadLocal để quản lý:

  • Request context

  • Session context

  • Transaction context



❌ Lưu ý khi dùng ThreadLocal#

1. Phải remove() khi xong việc#

ThreadLocal thường dùng trong thread pool (VD: server xử lý request). Nếu không gọi remove(), dữ liệu cũ sẽ rò rỉ bộ nhớ (memory leak).

try { threadLocal.set(data); // xử lý logic } finally { threadLocal.remove(); // cực kỳ quan trọng! }

2. Không nên lạm dụng#

  • Không dùng ThreadLocal để tránh thiết kế đúng.

  • Không thay thế hoàn toàn cho truyền tham số hoặc dependency injection.



So sánh ThreadLocal vs Biến toàn cục vs Biến cục bộ#

Loại biến Tính chia sẻ Phạm vi Thread-safe?
Biến toàn cục Tất cả thread Ứng dụng ❌ Không
Biến cục bộ Chỉ trong hàm 1 phương thức ✅ Có
ThreadLocal 1 thread Trong 1 thread ✅ Có


✅ Khi nào nên dùng ThreadLocal?#

  • Khi cần dữ liệu riêng biệt cho mỗi thread.

  • Khi cần tránh đồng bộ phức tạp.

  • Khi sử dụng các đối tượng không thread-safe (VD: SimpleDateFormat, NumberFormat).



🧠 Tổng kết#

ThreadLocal là gì? – Là một cách để lưu biến cục bộ riêng biệt cho mỗi thread trong Java. Dùng để làm gì? – Tránh race condition, giữ thông tin riêng cho mỗi thread, đặc biệt hữu ích trong môi trường đa luồng như web server.

Nếu bạn đang làm việc với đa luồng, xử lý đồng thời, hoặc xây dựng API backend, hãy học cách sử dụng ThreadLocal đúng cách để tăng hiệu suất và tránh bug khó lường.

Bài liên quan trong #Java

✓ Đã sao chép link