Thứ Bảy, 20 tháng 7, 2013

Introduction to thread local

Có thể bạn đã biết hoặc chưa biết về thread local nhưng như mình đã nói trong bài viết đầu tiên Buffer vs Cache có gì hay ho thì mình sẽ kể cho bạn nghe. Ở đây, trong khuôn khổ bài viết này, mình chỉ viết về thread local trong ngôn ngữ lập trình Java.

Thread local là một kỹ thuật khá là hay ho trong Java. Kỹ thuật này giúp lập trình viên giảm được các code thừa trong chương trình. Giảm code thừa rất quan trọng. Nó khiến chương trình dễ đọc và như thế dễ bảo trì, dễ mở rộng tính năng hơn. Một số bạn cho rằng giảm code thừa sẽ khiến chương trình nhỏ gọn hơn do đó hiệu suất hơn. Điều này cũng đúng nhưng mình nghĩ cái đáng giá của những kỹ thuật như thread local là giúp lập trình viên viết code dựa trên một cơ chế được hỗ trợ từ chính ngôn ngữ nên sẽ tận dụng được sức mạnh của ngôn ngữ đó. Chính điều này sẽ nâng cao hiệu suất của chương trình.

Thread local sẽ định ra mức truy xuất global và local đến một object bên trong một thread.

- Mức truy xuất global được định ra cho các method bên trong thread đến thread local. Bạn sẽ không cần truyền object đó đến từng method cần sử dụng. Kỹ thuật thread local sẽ giúp cho mọi method trong thread luôn có thể nhìn thấy object.

- Mức truy xuất local được định ra cho các thread khác. Những thread khác sẽ không thể truy xuất đến thread local của một thread. Nói cách khác object trong thread local sẽ không thể được nhìn thấy bên ngoài ranh giới của thread mà sở hữu nó.


Bây giờ tôi sẽ viết một chương trình đơn giản để minh họa. Giả sử có một kịch bản như sau: client gửi request đến service. Service sẽ gen một request id cho mỗi request. Bạn cần phải sử dụng request id này trong hầu hết các service method của service. Với yêu cầu này, thông thường bạn sẽ nghĩ đến việc truyền service id vào tất cả các service method cần sử dụng. Nhưng thử áp dụng khái niệm thread local vào đây, bạn sẽ không cần truyền request id nữa.


Bạn cần bốn classes. Tất cả đều đặt trong package com.java.underground.thread

Class đầu tiên có tên là Context:















Context là một đối tượng giữ các thông tin chung cần được tham chiếu nhanh chóng. Ví dụ: SecurityContext trong sping security chứa các thông tin về authentication hoặc ServletContext trong servlet container. Một container thì lại là một thùng chứa object và cung cấp các tiện ích thao tác trên các object đó.

Class thứ hai là MyThreadLocal:

















ThreadLocal được cung cấp sẵn trong Java language. Bạn chỉ cần biết để sử dụng thôi. MyThreadLocal cung cấp các method để set, get, unset object

Class thứ ba là ThreadLocalExample:























Bạn tao ra hai thread gọi là threadOne và threadTwo. Trong mỗi thread bạn tạo ra một context object. Bạn đặt context object vào thread local sử dụng các phương thức tĩnh của thread local nhờ vậy bạn có thể thực hiên doBusinessMethod() mà không cần truyền đối tượng context theo.

Class thứ tư là BusinessService:










Bạn có thể truy xuất đến context qua thread local. Bạn không cần truyền context theo. Bạn có thể thắc mắc làm sao JVM biết được thread local nào của thread nào. Dù MyThreadLocal được thiết kế là static nhưng nó được sử dụng ở trong thread nào thì sẽ local trong thread đó mà thôi. 

Kết quả bạn có thể đoán được là:

Output:
request id of thread: Thread-1
request id of thread: Thread-0


Nói qua về thread: Thread là một object nhưng là một object được sử dụng để tạo ra môi trường thực thi cho các object khác. Một object là thread thì GC sẽ không có quyền clean nó cho đến khi isAlive() của nó trả về false. Việc thực hiện thread không tuần tự như bạn khai báo. Như ví dụ trên bạn có thể thấy Thread-0 được khai báo trước nhưng lại chạy sau Thread-1. Lý do là vì scheduler - một thành phần trong kernel sẽ đảm nhận việc chọn thread nào để chạy. Không ai đoán được scheduler sẽ chọn thread nào nên lập trình multithread rất khó. Code trong mỗi thread lại chạy tuần tự khi thread đó được gọi thực hiện. Kể cả khi không lập trình multithread thì trong chương trình Java bạn viết luôn có một thread gọi là main thread: Một process có thể có nhiều thread và luôn có ít nhất một thread. Trước khi làm quen với multithread, bạn có thể thấy code trong main thread luôn được gọi tuần tự.


Thôi nhé, tôi đi ăn cơm đấy, đói quá rồi :D 

Tạm biệt. Hi vọng bài viết này có ích cho bạn

Tham khảohttp://java.dzone.com/articles/java-thread-local-%E2%80%93-how-use

1 nhận xét: