2010-07-22 35 views

Trả lời

13

Nếu bạn đang nói về việc sử dụng cơ chế khóa (hoặc thậm chí là các rào cản đồng bộ) chỉ cần sử dụng java.util.concurrent.Lock. Đề xuất rõ ràng là sử dụng số ReentrantLock ủy quyền cho số Synch. Đồng bộ là một AQS mà lần lượt sử dụng LockSupport.

Tất cả được thực hiện dưới dạng bìa cho bạn.

Edit:

Không chúng ta hãy đi qua những ứng dụng thực tiễn của AbstractQueuedSynchronizer (AQS).

Cấu trúc đồng thời mặc dù có thể rất khác nhau trong cách sử dụng của chúng, tất cả đều có thể có cùng chức năng cơ bản.

I.e. Dưới một số điều kiện công viên chủ đề này. Dưới một số điều kiện khác đánh thức một sợi lên.

Đây là bộ hướng dẫn rất rộng nhưng rõ ràng là hầu hết các cấu trúc đồng thời sẽ cần một số chức năng phổ biến để có thể xử lý các hoạt động đó cho chúng. Nhập AQS. Có năm rào cản đồng bộ chính.

  • ReentrantLock
  • ReadLock
  • WriteLock
  • Semaphore
  • CountDownLatch

Bây giờ, tất cả những lăm cấu trúc có bộ rất khác nhau của quy tắc khi sử dụng chúng. Một CountdownLatch có thể cho phép nhiều luồng chạy đồng thời nhưng buộc một (hoặc nhiều) chuỗi phải đợi cho đến khi ít nhất n số chuỗi đếm xuống trên chốt được cho biết.

ReentrantLock chỉ buộc một luồng tại một thời điểm để nhập một phần quan trọng và xếp hàng lên tất cả các chuỗi khác để chờ hoàn tất.

ReadLock cho phép bất kỳ số lượng chủ đề đọc nào vào phần quan trọng cho đến khi khóa viết được giải phóng.

Các ví dụ có thể tiếp tục, nhưng bức tranh lớn ở đây là tất cả đều sử dụng AQS. Điều này là do họ có thể sử dụng các chức năng nguyên thủy mà AQS cung cấp và thực hiện các chức năng phức tạp hơn trên đầu trang của nó. AQS cho phép bạn đỗ công viên và đánh thức đề tài (nếu cần), nhưng theo cách bạn có thể hỗ trợ nhiều chức năng phức tạp.

+0

W.: Tôi thấy LockSupport được sử dụng trong 'AbstractQueuedLongSynchronizer', làm bạn đề nghị đó là một loại lớp API nội bộ? Chỉ muốn xem bất kỳ đoạn mã minh họa nào cho nó ... – Max

+2

@Max LockSupport là một lớp tiện ích mà mọi người đều có thể sử dụng. Nó không nhất thiết phải là một lớp bên trong Unsafe.java là một ví dụ tốt về một lớp bên trong. LockSupport là công khai để những người khác có thể viết phiên bản riêng của họ về AQS –

+0

W.: Cảm ơn John, tôi biết đó là phần mở rộng. Câu trả lời của bạn khiến tôi viết lại câu hỏi: thường thì việc sử dụng 'AbstractQueuedSynchronizer' xuất hiện mơ hồ đối với tôi. – Max

1

chúng không có nghĩa là để sử dụng trực tiếp trong mã khách hàng; nhiều hơn để giúp xây dựng các lớp học đồng thời mới.

1

AQS là một lớp tuyệt vời để xây dựng các nguyên tắc tương tranh đồng thời - nhưng nó phức tạp và đòi hỏi một chút nghiên cứu để sử dụng nó đúng cách. Tôi đã sử dụng nó cho một vài thứ như lazy initialisation và một đơn giản nhanh chóng reusable latch.

Vì phức tạp như vậy, tôi không nghĩ AQS đặc biệt mơ hồ, nó có các javadocs tuyệt vời mô tả cách sử dụng nó đúng cách.

+0

Chính xác AQS là gì? – Pacerier

+0

java.util.concurrent.AbstractQueuedSynchronizer –

+0

thực sự: java.util.concurrent.locks.AbstractQueuedSynchronizer –

0

AFAIK, AbstractQueuedSynchronizer được sử dụng để quản lý quá trình chuyển đổi trạng thái. JDK sử dụng nó để mở rộng Sync, một lớp bên trong cho java.util.concurrent.FutureTask. Lớp Sync quản lý các trạng thái (READY, RUNNING, RAN, và CANCELED) của FutureTask và các chuyển tiếp giữa chúng.

Điều này cho phép, như bạn có thể biết, FutureTask chặn trên FutureTask.get() cho đến khi đạt đến trạng thái RAN.

Các vấn đề liên quan