2010-04-23 30 views
10

Tôi đang cố gắng tạo một LinkedHashMap đồng thời cho một kiến ​​trúc đa luồng.Thực hiện một LinkedHashMap đồng thời

Nếu tôi sử dụng Collections#synchronizedMap(), tôi sẽ phải sử dụng các khối được đồng bộ hóa để lặp lại. Việc triển khai này sẽ dẫn đến việc bổ sung thêm các phần tử.

Nếu tôi sử dụng ConcurrentSkipListMap thì có cách nào để triển khai Comparator để lưu trữ tuần tự, như được lưu trữ trong Danh sách liên kết hoặc hàng đợi không.

Tôi muốn sử dụng java được tích hợp sẵn thay vì gói của bên thứ ba.

EDIT:

Trong đồng thời LinkedHashMap này, nếu các phím được tên, tôi muốn đặt liên tiếp các phím đến họ. tức là giá trị mới sẽ được thêm vào lúc bắt đầu hoặc kết thúc, nhưng theo tuần tự.

Trong khi lặp lại, LinkedHashMap có thể được thêm vào với mục nhập mới hoặc bị xóa. nhưng lặp lại phải là chuỗi trong đó các mục nhập được thêm vào.

Tôi hiểu rằng bằng cách sử dụng Collections#synchronizedMap(), khối được đồng bộ hóa cho lặp lại sẽ phải được triển khai, nhưng bản đồ có thể sửa đổi được (mục có thể được thêm/xóa) trong khi đang được lặp lại.

+0

Bạn đang nói về điều gì? Bạn đang cố gắng "lưu trữ tuần tự"? Xin vui lòng cho biết thêm chi tiết - thật khó để hiểu những gì bạn đang thực sự cố gắng làm vào lúc này. –

+0

Bạn đang cố gắng lưu trữ tuần tự? Nếu các khóa của bạn có thứ tự xác định thì bạn sẽ có thể viết một Trình so sánh. Có lẽ bạn nên cung cấp thêm thông tin về các phím trong bản đồ của bạn và cách bạn muốn chúng được đặt hàng. –

Trả lời

1

Sử dụng Collections#synchronizedMap().

Theo niềm tin của tôi, nếu tôi sử dụng Collections.synchronizedMap(), tôi sẽ phải sử dụng các khối được đồng bộ hóa cho getter/setter.

Điều này không đúng. Bạn chỉ cần đồng bộ hóa phép lặp trên bất kỳ khung nhìn nào (keyset, values, entryset). Cũng xem tài liệu API abovelinked.

+0

nếu bản đồ đang được lặp lại, thì có thể cho chủ đề khác thêm hoặc xóa các phần tử khỏi bản đồ không? – Nilesh

+0

Việc triển khai này có dẫn đến việc bổ sung tuần tự các phần tử – Nilesh

+0

1) Không nếu bạn đồng bộ hóa lặp lại theo tài liệu (bạn đã nhấp vào liên kết chưa?). Đó là toàn bộ điểm đồng bộ hóa. 2) Có, phần bổ sung đã được đồng bộ hóa nội bộ, đó cũng là toàn bộ ý định của bạn, đúng không? – BalusC

2

Nếu bạn sử dụng bản đồ đã đồng bộ hóa, bạn không phải đồng bộ hóa bên ngoài, trừ khi lặp lại. Nếu bạn cần giữ lại thứ tự của bản đồ, bạn nên sử dụng SortedMap. Bạn có thể sử dụng ConcurrentSkipListMap, là chủ đề an toàn, hoặc một SortedMap khác kết hợp với synchronizedSortedMap.

2

A LinkedHashMap có danh sách được liên kết kép được thực hiện thông qua thẻ bắt đầu bằng #. Một FIFO chỉ làm thay đổi các liên kết trên một ghi (chèn hoặc loại bỏ). Điều này làm cho việc triển khai phiên bản khá đơn giản.

  1. Viết LHM với thứ tự chèn chỉ được phép.
  2. Chuyển sang ConcurrentHashMap làm thẻ bắt đầu bằng #.
  3. Bảo vệ #put()/#putIfAbsent()/#remove() bằng khóa.
  4. Tạo trường "tiếp theo" dễ bay hơi.

Khi lặp lại, không cần khóa vì bạn có thể theo dõi trường "tiếp theo" một cách an toàn. Đọc có thể được khóa miễn phí bằng cách chỉ ủy quyền cho CHM trên #get().

+0

Không phạm tội, nhưng tôi ghét nó khi mọi người nói như thế này. Tôi biết danh sách liên kết gấp đôi là gì. Tôi biết những gì là một hashtable. Nhưng một danh sách liên kết đôi chạy qua một hashtable nghĩa là gì? – Pacerier

+1

Vâng, thật khó để giải thích và hình dung. Xem [bản trình bày] này (http://concurrentlinkedhashmap.googlecode.com/files/ConcurrentCachingAtGoogle.pdf) nơi tôi đã thử. Ý tưởng là danh sách được liên kết duy trì thứ tự và yêu cầu tìm kiếm O (n). Một hashtable là không có thứ tự và tìm thấy một mục trong thời gian O (1). Sự kết hợp là mục nhập bảng băm có chứa các con trỏ danh sách để một mục được sắp xếp trong danh sách. Các mục trong danh sách có thể được thêm vào (thứ tự FIFO), được chuyển đến đầu/đuôi (thứ tự LRU), và được loại bỏ trong O (1) thời gian (đuổi). Điều này cung cấp một chèn hoặc truy cập bản đồ đặt hàng với giá rẻ. –

+1

không phải là nó đúng nếu tôi sắp xếp 'HashMap' của tôi, nó sẽ trở thành một hashmap" đặt hàng ", về cơ bản sẽ đánh bại mục đích của một' LinkedHashMap'? – Pacerier

1

Cho đến bây giờ, dự án của tôi đã sử dụng LRUMap từ Bộ sưu tập Apache nhưng dựa trên SequencedHashMap. Bộ sưu tập đề xuất ListOrderedMap nhưng không có chủ đề an toàn.

Tôi đã chuyển sang MapMaker từ Google Guava. Bạn cũng có thể xem CacheBuilder.

0

Um, câu trả lời đơn giản là sử dụng nhà cung cấp khóa tăng giá đơn điệu mà hoạt động của bạn Comparator hoạt động. Hãy suy nghĩ AtomicInteger và mỗi lần bạn chèn, bạn tạo một khóa mới sẽ được sử dụng để so sánh. Nếu bạn gộp khóa thực của mình, bạn có thể tạo một bản đồ nội bộ của OrderedKey<MyRealKeyType>.

class OrderedKey<T> implements Comparable<OrderedKey<T>> { 
    T realKey; 
    int index; 
    OrderedKey(AtomicInteger source, T key) { 
    index = source.getAndIncrement(); 
    realKey = key; 
    } 
    public int compareTo(OrderedKey<T> other) { 
    if (Objects.equals(realKey, other.realKey)) { 
     return 0; 
    } 
    return index - other.index; 
    } 


} 

này sẽ lọai trừ nhu cầu cho một so sánh tùy chỉnh, và cung cấp cho bạn một O đẹp (1) phương pháp để tính toán kích thước (trừ khi bạn cho phép loại bỏ, trong trường hợp này, đếm những người là tốt, vì vậy bạn chỉ có thể trừ "tất cả các loại bỏ thành công" từ "tất cả các thành công thêm", nơi thành công có nghĩa là một mục nhập thực sự đã được tạo hoặc xóa).

+0

Làm rò rỉ bộ nhớ phần mềm; bạn có thể muốn thêm WeakReference vào những thứ đắt tiền ... mặc dù những thứ đắt tiền có xu hướng khá tệ như các phím trong bản đồ, đôi khi bạn chỉ cần một danh sách động các bộ dữ liệu (và quá lười để tạo ra một đối tượng thực sự), và java thiếu cú ​​pháp để thể hiện một cách duyên dáng. Bằng cách sử dụng ngữ nghĩa bản đồ thực tế, tất nhiên, bạn muốn chèn bản đồ theo thứ tự an toàn, thứ tự OrderedKey cho phép bạn. – Ajax

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