5

Tôi đã cố gắng đọc triển khai Synchronous Queue
Nó không đơn giản đối với tôi. Dường như sử dụng danh sách được liên kết trong đó mỗi nút được liên kết với một chuỗi.
Và phần cốt lõi sử dụng vòng quay chờ đợi các nhiệm vụ được đặt trong hàng đợi.
Tôi đã tự hỏi tại sao một vòng quay được sử dụng thay vì một cái gì đó như wait/notify?
Bây giờ cách này một trong các lõi đã biến mất do vòng lặp quay liên tục này, phải không?
Tôi cố gắng để hiểu được điểm này và có được một sự hiểu biết sơ bộ thiết kế của Synchronous QueueCố gắng hiểu cơ chế của một hàng đợi đồng bộ

CẬP NHẬT
gì cũng đang gây phiền toái cho tôi là cách đề bồi bàn start/stop.

+0

Đó là cơ sở của thuật toán không có khóa - lưu ý rằng việc quay chỉ được thực hiện khi có thứ gì đó cần truyền. chuyển giao được thực hiện hoặc nếu không có gì để làm, phương pháp trả về – assylias

+0

@assylias: Trong hầu hết các phần của 'TransferQueue.transferer' có một' tiếp tục' không phải là một 'return'. Có một sự trở lại trong một vài trường hợp, trong đó trường hợp tôi không có ý tưởng gì xảy ra với những người phục vụ và khi nào/làm thế nào họ khởi động lại – Jim

Trả lời

4

Điểm của SynchronousQueue là để đồng bộ hóa một cái gì đó thường khá không đồng bộ - một chuỗi đặt một mục vào hàng đợi trong khi một chuỗi khác cố gắng lấy nó.

Thực tế, đây không phải là hàng đợi. Nó không có dung lượng, không có bộ nhớ trong. Nó chỉ cho phép lấy từ hàng đợi khi một quá trình khác hiện đang cố gắng đưa vào hàng đợi.

Ví dụ:

Quy trình A cố gắng đưa vào hàng đợi. Điều này chặn ngay bây giờ. Quy trình B cố gắng lấy từ hàng đợi. Vì ai đó đang cố gắng đưa, mục được chuyển từ A sang B và cả hai đều được bỏ chặn.

Quy trình B cố gắng lấy từ hàng đợi nhưng không ai cố gắng đặt. Vì vậy, B hiện bị chặn. Quy trình A hiện muốn đặt một mục. Bây giờ mục được chuyển sang B, và A và B không còn bị chặn nữa.

Về việc ngăn chặn:

Việc thực hiện Sun/Oracle JRE không sử dụng bỏ phiếu thay vì chờ đợi/thông báo mẫu nếu bạn làm một hoạt động theo thời gian (như "cố gắng đưa cho 1 giây"). Điều này có ý nghĩa: nó định kỳ thử lại cho đến khi hết thời gian. Khi bạn thực hiện thao tác không theo thời gian (như "mất, không cần biết phải mất bao lâu" nó sẽ sử dụng park, hoạt động trở lại nếu tình huống đã thay đổi. Trong cả hai trường hợp, một trong các lõi của bạn sẽ không ngừng quay vòng. for (;;) có nghĩa là "thử lại không chính xác" trong trường hợp này, nó không có nghĩa là "quay liên tục"

+0

Tôi nghĩ rằng không có chặn thực sự. Tôi có nghĩa là phần chặn được thực hiện thông qua một vòng lặp spin.Điều này vòng lặp "ăn" chu kỳ CPU. Tại sao không phải là chặn thực hiện thông qua một số hình thức của 'chờ đợi' hoặc' ngủ'? – Jim

+0

Bạn nghĩ rằng sai, sau đó ;-) Có chặn. Đó là lý do tại sao tài liệu API bạn liên kết mở ra với câu '" Hàng đợi chặn trong đó mỗi thao tác chèn phải chờ thao tác xóa tương ứng bằng một chuỗi khác và ngược lại. "' –

+1

Nhưng bạn đang trích dẫn javadoc.I đã đề cập mà tôi đã cố gắng để hiểu việc thực hiện, nơi tôi tìm thấy 'for (;;) {' trong việc thực hiện 'chuyển'. – Jim

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