Đ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"
Nguồn
2013-08-26 21:53:05
Đó 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
@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