Hãy nói về lớp hỗ trợ cơ bản trong gói JUC-AbstractQueuedSynchronizer (AQS)
Một loạt các lớp công cụ đồng thời trong gói juc là một trong những bài luận gồm tám phần thường được hỏi trong quá trình phát triển hàng ngày của chúng ta, đặc biệt là trong các cuộc phỏng vấn, dù cho công việc hay phỏng vấn, vì vậy hôm nay tôi muốn cố gắng mô tả những điều này cho mọi người. Tôi đã bắt đầu viết bài đăng trên blog này, nếu mã nguồn của từng lớp chung sẽ được đề cập trong tương lai, thì đó có thể là một chuỗi. Kế hoạch là bắt đầu từ AQS cấp độ tương đối thấp, sau đó kết hợp mã nguồn của ReentrantLock. để nói về việc triển khai cụ thể khóa độc quyền AQS, cũng như khóa và khóa mở sau đó hãy nói về cách sử dụng và nguyên tắc của các lớp khác trong gói JUC như CountDownLatch, CyclicBarrier, Phaser, ReadWriteLock, Semaphore, Exchanger và LockSupport. Nếu bạn có thời gian, chúng tôi sẽ nói về cách triển khai cụ thể dựa trên khóa chia sẻ AQS. trên mã nguồn của CountDownLatch Tiếp theo Không cần chần chừ gì nữa, hãy bắt tay vào cuộc hành trình khám phá những bí mật của AQS.
1. AQS là gì?
- Tên đầy đủ của AQS là Tóm tắtQueuedSynchronizer, có thể hiểu là một framework (lớp cơ sở) có thể thực hiện các khóa. Nó có thể thực hiện các khóa ở cả chế độ chia sẻ và độc quyền. Trên thực tế, nhiều lớp công cụ liên quan đến khóa trong gói juc cũng vậy. dựa trên AQS; nó cung cấp một số phương thức mẫu để các lớp con triển khai mở rộng và kết hợp với lớp Unsafe cơ bản để thực hiện các hoạt động an toàn dựa trên lớp nguyên thủy CPU, từ đó đạt được sự an toàn luồng trong môi trường đồng thời.
2. Nguyên tắc thực hiện AQS
- Lý do chính tại sao AQS có thể được sử dụng làm lớp cơ sở để triển khai chức năng khóa là vì nó duy trì biến trạng thái kiểu int và hàng đợi hai chiều FIFO có thể quyết định xem luồng có cần chặn hay không bằng cách kiểm soát giá trị trạng thái theo nhu cầu riêng của nó. Hàng đợi hai chiều được sử dụng để lưu trữ các luồng chưa cạnh tranh để giành tài nguyên khóa; và AQS đóng gói các phương thức có thể vận hành các giá trị trạng thái một cách an toàn theo luồng (một loạt các phương thức vận hành CAS) bằng cách kết hợp các khả năng của Lớp không an toàn, do đó người lập trình chỉ có thể tập trung vào Bạn không cần phải chú ý đến các chi tiết triển khai cơ bản khi sử dụng khóa;
- AQS hỗ trợ triển khai hai chế độ khóa, đó là khóa độc quyền và khóa chia sẻ. Việc triển khai cụ thể các khóa độc quyền được thể hiện bằng ReentrantLock và việc triển khai các khóa chia sẻ như CountDownLatch, CyclicBarrier, v.v.
Lưu ý: Do việc triển khai mã nguồn và lớp con của AQS sẽ được giới thiệu sau nên đây chỉ là mô tả bằng tiếng bản ngữ về nguyên tắc của AQS, tức là có hai điểm chính: trạng thái và hàng đợi hai chiều. chi tiết cần thảo luận, cân nhắc. Những chi tiết này sẽ được phản ánh trong mã nguồn tiếp theo và sẽ không được mô tả ở đây.
3. Phân tích tóm tắt mã nguồn AQS
1. biến trạng thái
trạng thái int dễ bay hơi riêng tư;
1. Trạng thái là trạng thái đồng bộ hóa do AQS cung cấp để mở rộng lớp con. Các lớp con có thể duy trì các trạng thái khác nhau để đạt được việc triển khai khóa với các hiệu ứng khác nhau. Ví dụ: ReentrantLock thể hiện hoạt động khóa bằng cách duy trì trạng thái là 0 hay 1. ;
2. Sử dụng sửa đổi dễ bay hơi chủ yếu để làm cho luồng hiển thị trong môi trường đồng thời.
2. Lớp nội bộ nút
- Lớp Node là một thành phần của hàng đợi CLH hai chiều. Biến luồng mà nó duy trì là luồng chưa cạnh tranh để giành khóa. Nó cũng duy trì một số thông tin quan trọng khác của hàng đợi CLH, chẳng hạn như nút trước đó của Nút hiện tại (prev). và các nút tiếp theo (tiếp theo), v.v., dán mã nguồn của Nút bên dưới.
static Final class Node { /** Cho biết nút hiện tại ở chế độ chia sẻ*/ static Final Node SHARED = new Node(); /** Cho biết nút hiện tại ở chế độ độc quyền*/ static Final Node EXCLUSIVE = null; /** waitStatus Giá trị tương ứng cho biết luồng đã bị hủy*/ static Final int CANCELED = 1; Giá trị tương ứng của WaitStatus cho biết rằng các luồng tiếp theo cần hủy đánh dấu*/ static Final int SIGNAL = -1; /** Giá trị tương ứng với WaitStatus chỉ ra rằng luồng đang chờ điều kiện thức dậy */ static Final int CONDITION = -2; ** * giá trị waitStatus để cho biết AcacquiShared tiếp theo nên * lan truyền vô điều kiện */ static Final int PROPAGATE = -3 ; /** * Trạng thái chờ, các giá trị liệt kê lần lượt là 1, 0, -1, -2 và -3 tương ứng với các giá trị biến trên, 0 có nghĩa là không có trạng thái nào ở trên */volatile int waitStatus ; /** * Nút trước của Nút hiện tại*/ Nút dễ bay hơi trước đó; * * Nút chờ tiếp theo, được sử dụng ở trạng thái Điều kiện */ Nút nextWaiter; /** * Trả về true nếu nút đang chờ ở chế độ chia sẻ. */ Final boolean isShared() { return nextWaiter == SHARED; } /** * Lấy nút tiền thân của hàng đợi hiện tại* * @return tiền thân của nút này */ Final Node tiền nhiệm() ném NullPointerException { Node p = prev ; if (p == null) ném new NullPointerException(); ngược lại trả về p; } Node() { // Được sử dụng để thiết lập phần đầu hoặc điểm đánh dấu CHIA SẺ } Node(Luồng luồng, chế độ nút) { // Được sử dụng bởi addWaiter this.nextWaiter = mode; this.thread = thread; } Node(Luồng luồng, int waitStatus) { // Được sử dụng bởi Điều kiện this.waitStatus = waitStatus; = chủ đề;
3. Phương thức mẫu AQS để mở rộng lớp con
Các phương thức chế độ dành riêng cho các lớp con triển khai
-
tryAcquire(int) cố gắng lấy khóa, trả về true nếu thành công và false nếu thất bại.
-
tryRelease(int) cố gắng giải phóng khóa. Nó trả về true nếu việc giải phóng thành công và sai nếu thất bại.
Các phương thức mẫu được chia sẻ để các lớp con triển khai
-
thửAcquireshared(int) 。
Cố gắng lấy khóa, số âm biểu thị thất bại; 0 biểu thị thành công, nhưng không còn tài nguyên nào sẵn có; số dương biểu thị thành công và còn lại tài nguyên.
-
thửReleaseshared(int) 。
Cố gắng mở khóa, trả về true nếu thành công, false nếu thất bại.
Trên đây giới thiệu sơ lược về nguyên tắc của AQS và một số nhận xét về mã nguồn Tiếp theo, tôi sẽ viết một bài liên quan đến việc giải nghĩa mã nguồn ReentrantLock để trải nghiệm thực tế sử dụng AQS.
Cuối cùng, bài viết này nói về lớp hỗ trợ cơ bản trong gói JUC - Tóm tắtQueuedSynchronizer (AQS). Nếu bạn muốn biết thêm về lớp hỗ trợ cơ bản trong gói JUC - Tóm tắtQueuedSynchronizer (AQS), vui lòng Tìm kiếm các bài viết CFSDN hoặc tiếp tục duyệt các bài viết liên quan. Tôi hy vọng bạn sẽ ủng hộ blog của tôi trong tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!