2015-05-19 17 views
5

Các tài liệu của hầu hết các bộ sưu tập trong thư viện chuẩn Java như ConcurrentLinkedQueue, ConcurrentLinkedDequeueConcurrentSkipListSet đi kèm với khuyến cáo sau đây:kích thước bộ sưu tập đồng thời tính toán

Ghi chú rằng, không giống như ở hầu hết các bộ sưu tập, phương pháp kích thước không phải là một hoạt động liên tục. Do tính chất không đồng bộ của các tập hợp này, việc xác định số phần tử hiện tại yêu cầu phải có thông số ngang qua và do đó có thể báo cáo kết quả không chính xác nếu bộ sưu tập này được sửa đổi trong quá trình truyền tải.

Điều đó có nghĩa là gì? Tại sao họ không thể giữ một bộ đếm (ví dụ: AtomicInteger) và chỉ trả lại giá trị cho các cuộc gọi đến size()?

Có phải vì bộ đếm phải được đồng bộ hóa và do đó tạo ra một điểm bị tắc nghẽn?

Lưu ý phụ, ConcurrentHashMap dường như không có vấn đề này. Tại sao vậy? Nhìn vào mã nguồn, có vẻ như nó sử dụng nhiều bộ đếm được giữ trong một mảng được tổng kết các cuộc gọi đến size(). Đó có phải là để phá vỡ điểm sặc hay có lý do nào khác không?

+0

bộ đếm nguyên tử chắc chắn sẽ không tốt. – ZhongYu

Trả lời

5

Sử dụng tài nguyên được chia sẻ để duy trì kích thước() sẽ tốn kém và khá vô ích. size() có thể không chính xác ngay sau khi nó trở lại vì bạn không thể giữ một khóa trên bộ sưu tập để nó có thể thay đổi giữa bạn gọi nó và khi bạn nhận được giá trị.

ConcurentHashMap có cùng cách tiếp cận. Kích thước() có thể không chính xác trước khi phương thức trả về.

+0

Tất nhiên 'size()' không thể tin cậy hoàn toàn, tôi chấp nhận điều đó. Nhưng vấn đề tôi có là chi phí không đổi của việc vượt qua mọi phần tử trong bộ sưu tập để đếm chúng. Nhưng tôi đoán tôi đã đúng về điểm nghẹt thở rồi? –

+1

@GustavKarlsson Câu đầu tiên của Peter thực sự giải quyết được lý do. Đồng bộ hóa và mất hiệu lực bộ nhớ cache sẽ rất tốn kém cho hàng đợi hoạt động. Có, bạn đã đúng, chắc chắn sẽ có một cổ chai ở đó. Đó là một trong những vấn đề chính với 'ReentrantReadWriteLock' –

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