7

Tôi cần một bản đồ với các yêu cầu sau:Bản đồ đồng thời với kích thước cố định

  1. Nó nên được đánh giá cao đồng thời. Các phương thức put(), get()remove() có thể được gọi bởi nhiều luồng cùng một lúc.

  2. Nó phải có kích thước cố định. Nếu kích thước của HashMap đạt đến giá trị tối đa (ví dụ: 10000), thì không được phép thêm mục nhập mới vào bản đồ. KHÔNG THỂ là bộ nhớ cache LRU nơi mục nhập cũ nhất bị xóa khi đạt đến kích thước tối đa.

ConcurrentHashMap có thể đáp ứng # 1. Nhưng, không chắc làm thế nào # 2 có thể được thực hiện trên đầu trang của ConcurrentHashMap mà không ảnh hưởng đến sự tương tranh (Thêm một phương thức tùy chỉnh put() sẽ thêm vào bản đồ chỉ khi kích thước nhỏ hơn kích thước tối đa, cần phải được "đồng bộ". mục đích sử dụng đồng thời HashMap).

Vui lòng cho tôi biết suy nghĩ của bạn.

+3

kiểm tra kích thước trước khi đặt? – vefthym

+2

trong concurrenthashmap kích thước được báo cáo là không chính xác. có thể sử dụng concurrenthashmap với một semaphore đếm? –

+1

"không chắc chắn làm thế nào # 2 có thể được thực hiện trên đầu trang của ConcurrentHashMap mà không ảnh hưởng đến đồng thời" ... Tôi không thấy lý do tại sao nó sẽ là một vấn đề. Bạn tạo ra một wrapper rằng, trên cùng của bản đồ đồng thời giới thiệu truy cập. Để đồng bộ hóa quyền truy cập vào bộ đếm, bạn sử dụng nguyên gốc syncronizing của riêng mình (ví dụ: ReentrantLock) để giảm thiểu chi phí bổ sung và tách nó khỏi đồng bộ hóa bản đồ đồng thời. Sau đó, mọi thứ sẽ hoạt động tốt – heorhi

Trả lời

6

Bạn có thể thực hiện một bản đồ đại diện cho ConcurrentHashMap, sử dụng một semaphore đếm để giới hạn số lượng các mục trong bản đồ. Lớp Semaphore sử dụng một int được cập nhật nguyên tử để theo dõi các giấy phép, vì vậy nó sẽ không phải trả thêm phí.

+2

Sử dụng 'tryAcquire' của' Semaphore' trước khi 'put' và' release' sau 'remove', vì bạn không muốn chặn. –

2

Bạn có thể tự làm tất cả những điều này và bản thân kho SE của java có thể cung cấp những gì bạn yêu cầu, nhưng tôi khuyên bạn nên sử dụng phương pháp dễ dàng hơn và dễ mở rộng hơn khi tự làm tất cả công việc này. Hãy thử một trong những trong lưới dữ liệu bộ nhớ:

Ví dụ trong ehcache bạn có thể đạt được những gì bạn muốn bằng một cấu hình tương tự như:

<cache 
name="myCache" 
maxElementsInMemory="10000" 
eternal="true" 
overflowToDisk="false" /> 
+0

Nhược điểm chính là rằng điều này sẽ có nhiều đơn đặt hàng của cường độ chậm hơn. –

+0

Tôi có thể đồng ý rằng nó sẽ nhưng sau đó một lần nữa nên được chọn lọc khi lựa chọn những gì để tối ưu hóa. Một số bản đồ băm được phân phối mà tôi sử dụng chứa trên hàng triệu dữ liệu ở các vùng riêng biệt với các dịch vụ liên quan của chúng phản hồi trong khung thời gian có thể chấp nhận được. Xem xét tất cả những điều đó, 10000 là một con số rất nhỏ. – Pumpkin

+1

Tôi chưa kiểm tra chi tiết, nhưng, tôi không cần bộ nhớ cache được phân phối. Tôi có thể sống với một bản đồ băm đơn giản đáp ứng các yêu cầu nêu trên. Vì vậy, có nghĩa là ConcurrentHashMap với semaphore có ý nghĩa hơn? –

0

Nếu sử dụng ConcurrentHashMap, đây là lựa chọn hiển nhiên ở đây, sau đó sử dụng đầu vào concurrencyLevel cho hàm tạo để tăng băng thông - phân đoạn này thành nhiều khu vực để tránh xung đột các lần đặt.

+0

Thay đổi 'concurrencyLevel' không có cách nào giải quyết vấn đề của mình về ConcurrentMap có kích thước cố định. –

+0

Đồng ý. Điều này sẽ không giải quyết vấn đề ConcurrentMap kích thước cố định. –

+0

Đồng ý với tôi, nhưng nó sẽ cải thiện sự tương tranh, đó là mối quan tâm khác của anh ấy. Đáng chú ý. –

0

Làm thế nào về việc duy trì kích thước của Hashmap mọi lúc để đảm bảo tổng số phần tử được chèn vào? Bạn có thể sử dụng AtomicInteger để bạn không phải đồng bộ hóa/khóa một int thường xuyên và hy sinh lợi ích của việc sử dụng ConcurrentHashMap.

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