Các lớp tiện ích đồng thời trong Java
Gói
java.util.concurrent
(viết tắt là J.U.C) trong JDK cung cấp một số lớp tiện ích đồng thời rất hữu ích.
CountDownLatch
CountDownLatch
có nghĩa đen là “khóa đếm giảm”. Nó được sử dụng để điều khiển một luồng chờ đợi nhiều luồng khác.
CountDownLatch
duy trì một bộ đếm (count) đại diện cho số lượng sự kiện cần chờ đợi. Phương thứccountDown
giảm giá trị của bộ đếm, đại diện cho một sự kiện đã xảy ra. Luồng gọi phương thứcawait
sẽ bị chặn cho đến khi bộ đếm trở thành 0, hoặc luồng đang chờ bị gián đoạn, hoặc thời gian chờ đợi đã hết.
CountDownLatch
được triển khai dựa trên AQS (AbstractQueuedSynchronizer
).
Phương thức khởi tạo duy nhất của CountDownLatch
:
Giải thích:
count
là giá trị đếm.
Các phương thức quan trọng của CountDownLatch
:
Giải thích:
await()
- Luồng gọiawait()
sẽ bị treo, nó sẽ chờ cho đến khi giá trị đếm trở thành 0 trước khi tiếp tục thực thi.await(long timeout, TimeUnit unit)
- Tương tự nhưawait()
, chỉ khác là chờ một khoảng thời gian nhất định trước khi tiếp tục thực thi nếu giá trị đếm vẫn chưa trở thành 0.countDown()
- Giảm giá trị đếm đi 1.
Ví dụ:
CyclicBarrier
CyclicBarrier
có nghĩa đen là “rào chắn lặp lại”.CyclicBarrier
cho phép một nhóm luồng chờ đến một trạng thái (gọi là rào chắn) trước khi cùng tiếp tục thực thi. Tên gọi “rào chắn lặp lại” xuất phát từ việc sau khi tất cả các luồng chờ đã được giải phóng,CyclicBarrier
có thể được sử dụng lại.
CyclicBarrier
duy trì một bộ đếm (count). Mỗi lần gọi phương thứcawait
, count tăng lên 1, cho đến khi giá trị của count bằng giá trị được thiết lập, tất cả các luồng đang chờ sẽ tiếp tục thực thi cùng nhau.
CyclicBarrier
được triển khai dựa trên ReentrantLock
và Condition
.
Ứng dụng của CyclicBarrier
: CyclicBarrier
rất hữu ích trong các thuật toán lặp song song.
CyclicBarrier
cung cấp 2 phương thức khởi tạo:
Giải thích:
parties
- Số lượng luồng cần chờ đến trạng thái rào chắn.barrierAction
- Hành động được thực thi khi rào chắn đạt trạng thái.
Các phương thức quan trọng của CyclicBarrier
:
Giải thích:
await()
- Chờ đến khi số lượng luồng gọiawait()
đạt đến giá trị rào chắn. Nếu luồng hiện tại là luồng cuối cùng đến và một hành động rào chắn không rỗng được cung cấp trong hàm tạo, luồng hiện tại sẽ thực thi hành động đó trước khi cho phép các luồng khác tiếp tục. Nếu có ngoại lệ xảy ra trong quá trình hành động rào chắn, ngoại lệ đó sẽ được truyền lại trong luồng hiện tại và rào chắn sẽ bị hỏng.await(long timeout, TimeUnit unit)
- Tương tự nhưawait()
, nhưng chờ một khoảng thời gian nhất định trước khi cho phép các luồng đạt đến rào chắn tiếp tục thực thi.reset()
- Đặt lại rào chắn về trạng thái ban đầu.
Ví dụ:
Semaphore
Semaphore
có nghĩa đen là “nguồn tín hiệu”.Semaphore
được sử dụng để kiểm soát số lượng đồng thời của một đoạn mã.
Semaphore
quản lý một tập hợp các quyền ảo (permit), số lượng quyền ban đầu có thể được chỉ định thông qua phương thức khởi tạo. Mỗi lần gọi phương thứcacquire
sẽ lấy một quyền, nếu không có quyền nào sẵn có thì sẽ chờ; và phương thứcrelease
sẽ giải phóng một quyền.
Ứng dụng của Semaphore
:
Semaphore
có thể được sử dụng để triển khai bể tài nguyên, ví dụ như bể kết nối cơ sở dữ liệu.Semaphore
có thể được sử dụng để biến bất kỳ loại bộ chứa nào thành bộ chứa chặn có giới hạn.
Semaphore
cung cấp 2 phương thức khởi tạo:
Giải thích:
permits
- Khởi tạo một số lượng quyền cố định và mặc định không công bằng.fair
- Xác định xem Semaphore có hoạt động công bằng hay không. Công bằng có nghĩa là cho phép luồng chờ lâu hơn được ưu tiên lấy quyền.
Các phương thức quan trọng của Semaphore
:
Giải thích:
acquire()
- Lấy 1 quyền.acquire(int permits)
- Lấy một số lượng quyền.release()
- Giải phóng 1 quyền.release(int permits)
- Giải phóng một số lượng quyền.
Ví dụ:
Tổng kết
CountDownLatch
vàCyclicBarrier
đều được sử dụng để chờ đợi giữa các luồng, chỉ khác nhau ở điểm chính:CountDownLatch
thường được sử dụng khi một luồng A chờ đợi cho đến khi một số luồng khác hoàn thành nhiệm vụ trước khi nó tiếp tục thực thi.CyclicBarrier
thường được sử dụng khi một nhóm luồng cần chờ đến một trạng thái cụ thể trước khi cùng tiếp tục thực thi.- Ngoài ra,
CountDownLatch
không thể tái sử dụng, trong khiCyclicBarrier
có thể tái sử dụng.
Semaphore
tương tự như khóa, nó được sử dụng để kiểm soát quyền truy cập vào một tập hợp tài nguyên.