2010-05-20 25 views
6

Tôi đang tìm bản triển khai bản đồ băm tốt. Cụ thể, một trong số đó là tốt cho việc tạo ra một số lượng lớn các bản đồ, hầu hết trong số đó là nhỏ. Vì vậy, bộ nhớ là một vấn đề. Nó nên được thread-an toàn (mặc dù mất lẻ đặt có thể là một thỏa hiệp OK để trở lại cho hiệu suất tốt hơn), và nhanh chóng cho cả hai nhận được và đặt. Và tôi cũng muốn trăng trên một cây gậy, xin vui lòng, với một trật tự phụ của công lý.Java: bản đồ đa luồng: các so sánh triển khai như thế nào?

Các tùy chọn tôi biết là:

  • HashMap. Vô hại un-thread an toàn.

  • ConcurrentHashMap. Lựa chọn đầu tiên của tôi, nhưng điều này có một dấu chân bộ nhớ khổng lồ - khoảng 2k mỗi trường hợp.

  • Collections.sychronizedMap (HashMap). Đó là làm việc OK cho tôi, nhưng tôi chắc chắn phải có lựa chọn thay thế nhanh hơn.

  • Trove hoặc Colt - Tôi nghĩ rằng không phải cái nào trong số này an toàn cho thread, nhưng có lẽ mã có thể được điều chỉnh để được an toàn chỉ.

Mọi người khác? Bất kỳ lời khuyên về những gì nhịp đập những gì khi nào? Bất kỳ thuật toán bản đồ băm mới thực sự tốt nào mà Java có thể sử dụng thực hiện?

Cảm ơn trước về thông tin bạn đã nhập!

+0

Đừng quên HashTable cũ. Không được chấp nhận, nhưng vẫn được tìm thấy xung quanh mã Java kế thừa. – Uri

+1

@Uri: đó là Hashtable với chữ thường t :) Nói về di sản .. – BalusC

+0

Bạn cũng có thể quản lý một số mở rộng dấu chân của ConcurrentHashMap bằng cách điều chỉnh đối số constructor concurrencyLevel. – Affe

Trả lời

0

Vâng, có một Colt sprise-up trong Apache Mahout. Nó vẫn không có trong kinh doanh hiện tại. Có gì sai khi bảo vệ mã bằng một khối được đồng bộ hóa? Bạn có đang mong đợi một số chương trình phức tạp mang tính ma quái giữ khóa cho độ chi tiết nhỏ hơn put hoặc get?

Nếu bạn có thể viết mã, vui lòng đóng góp cho Mahout.

+0

Tôi nghĩ rằng tôi cần phải đồng bộ hóa cả hai được và đặt, như nếu không một rehash có thể gây ra get() để trả lại rác. Và việc đồng bộ hóa đó sẽ nằm trên bản đồ (không phải là chìa khóa). Nó sẽ hoạt động, nhưng cảm thấy ít hơn tối ưu. –

+0

Đó là ý của tôi, nhiều hay ít. – bmargulies

0

Bạn nên xem bản đồ băm liên tục trong Clojure.

Đây là những cấu trúc dữ liệu an toàn không thay đổi, có thể so sánh với hiệu năng Java HashMaps cổ điển. Bạn rõ ràng cần phải quấn chúng nếu bạn muốn có một bản đồ có thể thay đổi được, nhưng điều đó không khó.

http://clojure.org/data_structures

6

Collections.synchronizedMap() chỉ đơn giản là làm cho tất cả các phương pháp Mapsynchronized.

ConcurrentMap thực sự là giao diện bạn muốn và có một số triển khai (ví dụ: ConcurrentHashMap, ConcurrentSkipList). Nó có một số hoạt động mà Map đó không phải là quan trọng cho các hoạt động threadsafe. Thêm vào đó là chi tiết hơn so với Map được đồng bộ hóa vì một thao tác sẽ chỉ khóa một phần cấu trúc dữ liệu sao lưu chứ không phải toàn bộ điều.

3

Tôi không có kinh nghiệm về những điều sau đây, nhưng tôi đã làm việc với một dự án khi đã thề Javolution cho các tác vụ thời gian thực và bộ nhớ nhạy cảm.

Tôi nhận thấy trong API có FastMap tuyên bố là chuỗi an toàn.Như tôi đã nói, tôi đã không có ý tưởng nếu nó bất kỳ tốt cho bạn, nhưng đáng xem:

API for FastMap

Javolution Home

+0

Cảm ơn - FastMap trông thú vị và có thể cấu hình cao. –

2

Rất ngạc nhiên khi có bản in 2k! Cách đặt cài đặt đồng thời của ConcurrentHashMap thấp hơn (ví dụ: 2-3) và tối ưu hóa kích thước ban đầu (= nhỏ hơn).

Tôi không biết tiêu thụ bộ nhớ đó đến từ đâu, nhưng có thể nó có liên quan đến việc duy trì khóa sọc. Nếu bạn hạ thấp cài đặt đồng thời, nó sẽ có ít hơn.

Nếu bạn muốn có hiệu suất tốt với an toàn chủ đề vượt trội, ConcurrentHashMap thực sự tốt đẹp.

+0

Doh! Không xảy ra với tôi, bạn có thể điều chỉnh cài đặt của ConcurrentHashMap. –

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