2012-04-27 46 views
12

Tôi có một lớp bộ nhớ cache có chứa một volatile HashMap<T> để lưu trữ các mục trong bộ nhớ cache.Dễ bay hơi HashMap vs ConcurrentHashMap

Tôi tò mò điều gì sẽ là hậu quả của việc thay đổi volatile HashMap thành ConcurrentHashMap?

Tôi có tăng hiệu suất không? Bộ nhớ cache này là bộ nhớ đệm chỉ đọc.

Tùy chọn nào tốt nhất để sử dụng? chỉ HashMap? Bộ nhớ cache đang được phổ biến trên một khoảng thời gian.

+3

Nếu đó là chỉ đọc, bạn cần ... không. –

+4

'volatile' trên một' HashMap' có nghĩa là bạn vượt qua một rào cản bộ nhớ khi bạn nhận/đặt đối tượng 'HashMap'. Không có gì khi bạn thêm hoặc xóa mọi thứ khỏi bản đồ – Gray

+0

@BrianRoach bạn sẽ sử dụng những gì? – DarthVader

Trả lời

31

Đầu tiên, có vẻ như bạn không hiểu từ khóa volatile là gì. Nó đảm bảo rằng nếu giá trị tham chiếu được tổ chức bởi biến được khai báo volatile thay đổi, các chủ đề khác sẽ thấy thay vì có bản sao được lưu trong bộ nhớ cache. Không có liên quan gì đến an toàn luồng liên quan đến việc truy cập vào HashMap

Cho rằng, và thực tế là bạn nói HashMap là chỉ đọc ... bạn chắc chắn không cần phải sử dụng bất kỳ thứ gì cung cấp chỉ- an toàn bao gồm một Sửa ConcurrentHashMap

thêm: chỉnh sửa cuối cùng của bạn bây giờ bạn nói "Bộ nhớ cache đã được dân cư trên một khoảng"

đó là không chỉ đọc rồi, phải không?

Nếu bạn sắp có chủ đề đọc từ nó trong khi bạn đang viết (cập nhật HashMap hiện có) thì bạn nên sử dụng ConcurrentHashMap, có.

Nếu bạn đang Populating một hoàn toàn mới HashMap sau đó gán nó vào biến hiện có, sau đó bạn sử dụng volatile

+0

cũng là lý do tại sao tôi đã sử dụng dễ bay hơi, đã có một chủ đề nền đọc từ tập tin và tạo ra một hashmap mới sau đó gán cho bộ nhớ cache. Tôi đang có kế hoạch thay đổi thiết kế, đó là lý do tại sao tôi hỏi. Bạn đã trả lời cả hai trường hợp. Cảm ơn. – DarthVader

+0

Thực ra bạn có thể sử dụng 'volatile' để đảm bảo mọi người thấy các phần tử mới nhất (về cơ bản giống như cách bạn làm để có được các phần tử mảng" dễ bay hơi "), nó chỉ là a) hiệu suất kém, b) phức tạp, c) không giúp đỡ với các điều kiện cuộc đua nội bộ khi thêm dữ liệu và d) đồng bằng ngu ngốc. Nhưng doable! ;) – Voo

+0

@Voo bạn sẽ sử dụng cái gì? hoặc bạn sẽ làm thế nào? – DarthVader

6

Bạn nói bộ nhớ cache là chỉ đọc, mà còn được cập nhật trên một khoảng thời gian mà dường như mâu thuẫn.

Nếu toàn bộ bộ nhớ cache được cập nhật trong một khoảng thời gian, tôi sẽ tiếp tục sử dụng biến động. Biến động sẽ đảm bảo rằng bản đồ cập nhật được xuất bản một cách an toàn.

public final class Cache 
{ 
    private volatile Map<?,?> cache; 

    private void mapUpdate() { 
     Map<?,?> newCache = new HashMap<>(); 

     // populate the map 

     // update the reference with an immutable collection 
     cache = Collections.unmodifiableMap(newCache); 
    } 
} 

Nếu bản cập nhật khoảng được sửa đổi bộ nhớ cache tương tự, sau đó bạn có thể muốn sử dụng một ConcurrentHashMap, hoặc sao chép bản đồ, cập nhật các bản sao, và cập nhật các tài liệu tham khảo.

public final class Cache 
{ 
    private volatile Map<?,?> cache; 

    private void mapUpdate() { 
     Map<?,?> newCache = new HashMap<>(cache); 

     // update the map 

     // update the reference with an immutable collection 
     cache = Collections.unmodifiableMap(newCache); 
    } 
} 
+0

Tôi sẽ xem xét giữ trường bộ nhớ cache không dễ bay hơi. Do liên kết trường Collections.unmodifiableMap cuối cùng đến phiên bản mới của bản đồ sẽ được xuất bản một cách an toàn. Tại một số thời điểm, tất cả các luồng sẽ tải lên phiên bản mới của bản đồ bộ nhớ cache. Thông thường (nhưng không phải luôn luôn!) Không quan trọng nếu bộ nhớ cache sẽ có sẵn không ngay lập tức nhưng trong vài phần nghìn giây. Và làm cho trường này không dễ bay hơi cải thiện hiệu suất bộ nhớ cache CPU một chút. – vlsergey

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