2012-05-14 31 views
10

Tôi đã tham gia một cái nhìn tại các mã nguồn cho WeakHashMap và tình cờ này:Tôi có nên đồng bộ hóa trên một ReferenceQueue không?

private final ReferenceQueue<Object> queue = new ReferenceQueue<>(); 

private void expungeStaleEntries() { 
    for (Object x; (x = queue.poll()) != null;) { 
     synchronized (queue) { 
      /* snip */ 
     } 
    } 
} 

Tại sao phương pháp này đồng bộ hóa trên ReferenceQueue? WeakHashMap chính nó không tuyên bố là chuỗi an toàn:

Giống như hầu hết các lớp thu thập, lớp này không được đồng bộ hóa. A WeakHashMap được đồng bộ hóa có thể được xây dựng bằng phương pháp Collections.synchronizedMap.

nào khiến tôi tin rằng chi tiết thực hiện điều này là, bằng cách nào đó, đảm bảo sự an toàn thread của ReferenceQueue tự (kể từ khi GC sẽ được sửa đổi nó từ riêng của mình Thread). Tuy nhiên, the documentation for ReferenceQueue không đề cập đến bất kỳ điều gì về bất kỳ mối quan tâm đồng thời nào và xem mã nguồn cho ReferenceQueue cho thấy rằng nó thậm chí không đồng bộ hóa chính nó (nó sử dụng khóa nội bộ).

Tại sao WeakHashMap đồng bộ hóa trên ReferenceQueue? Tôi có nên đồng bộ hóa trên ReferenceQueue mỗi khi tôi sử dụng?

Trả lời

6

Nếu bạn nhìn vào ReferenceQueue, bạn sẽ thấy rằng nó hỗ trợ rõ ràng luồng bên trong nền tảng, bởi vì nó nói rằng phương pháp remove() sẽ chặn cho đến khi có mục nhập mới.

synchronized bạn thấy trong WeakHashMap là về việc đảm bảo rằng nhiều chuỗi truy cập ReferenceQueue được đồng bộ hóa đúng cách.

Bạn có thể tìm thấy điều này liên quan bug at bugs.sun.com thú vị.

Để trả lời câu hỏi của bạn, tôi nghĩ rằng đồng bộ hóa bên ngoài của ReferenceQueue là không bắt buộc nếu bạn đảm bảo nó chỉ được truy cập bởi một chuỗi duy nhất. Tôi sẽ không sử dụng (và không thể nghĩ ra một lý do chính đáng) để sử dụng một đơn ReferenceQueue làm người tiêu dùng từ nhiều chủ đề.

+0

+1 Tìm kiếm thú vị - Thú vị cách một phương pháp đọc có thể sửa đổi bản đồ. –

+1

@andersoj Ahh, báo cáo lỗi đó làm rõ. Vì gọi 'size' trên' WeakHashMap' có thể sửa đổi bản đồ bên dưới, người dùng đồng thời gọi 'kích thước' trên một bản đồ có thể vô tình làm hỏng nó. Hành vi này là trái với hầu hết (tất cả?) Khác JDK 'Map' triển khai mà sẽ cho phép nhiều chủ đề để đọc nội dung của họ mà không có vấn đề, vì vậy họ quyết định làm cho lớp một chút thread an toàn để duy trì tính nhất quán với' Đặc tả bản đồ. – Jeffrey

+0

@John Vint ví dụ LinkedHashMap sửa đổi bản đồ vì nó lưu trữ lệnh đặt hàng – gstackoverflow

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