2012-06-19 40 views
9

Ngay bây giờ tôi đang cố gắng tạo ra một nhà sản xuất/người tiêu dùng chủ đề, các nhà sản xuất thread đi qua tất cả các kết hợp có thể có của các chữ cái và tạo ra MD5 băm tương ứng của họ. Sau đó, mỗi kết hợp và băm của nó được đưa vào HashMap<String,String>. Bây giờ trong chuỗi tiêu dùng của tôi, tôi muốn có thể sử dụng bộ sưu tập Queue<> trên băm sao cho chuỗi tiêu dùng của tôi có thể gọi poll() v.v ... do đó loại bỏ các giá trị atc như một Queue nhưng vẫn cho tôi khả năng nhìn thấy cả kết hợp lẫn hàm băm của nó khi gọi poll() Tôi sẽ đi đâu để tới đó? Tôi có số HashMap nhưng không biết cách 'tạo' hoặc truyền nó thành Hàng đợi. Cảm ơn.Có thể tạo Hàng đợi cho bộ HashMap không?

Trả lời

7

Bạn không nên sử dụng HashMap mà không cần xử lý an toàn luồng của mã của bạn. Khác, bạn có thể kết thúc bằng Live-lock.

Để có thể lặp lại Bản đồ của bạn với thứ tự mà các phím được chèn vào, bạn có thể sử dụng LinkedHashMap.

Map m = Collections.synchronizedMap(new LinkedHashMap(...)); 

Nhà sản xuất sẽ đẩy các mục như thế này (không có gì đặc biệt):

m.put(key, object) 

Người tiêu dùng sẽ thăm dò ý kiến ​​các mục như thế này:

while (someCondition) { 
    Map.Entry nextEntry = null; 

    // This block is equivalent to polling 
    { 
     synchronized(s) { 
      Iterator i = s.iterator(); // Must be in the synchronized block 
      if (i.hasNext()) { 
       nextEntry = i.next(); 
       i.remove(); 
      } 
     } 
    } 

    if (nextEntry != null) { 
     // Process the entry 
     ... 
    } else { 
     // Sleep for some time 
     ... 
    } 
    // process 
} 
+0

Cảm ơn bạn đã làm việc này một cách quyến rũ và nhanh chóng, dễ dàng và rõ ràng để triển khai –

5

Các LinkedHashMap loại giống như một sự kết hợp của một HashMapQueue - nó lưu cặp khóa/giá trị mà còn nhớ thứ tự mà chúng được chèn vào. Đây có thể chính xác là loại bạn đang tìm kiếm. Không có hàm poll() rõ ràng, nhưng nếu bạn nhận được một trình lặp trên LinkedHashMap, bạn sẽ truy cập các phần tử theo thứ tự chúng được thêm vào. Sau đó, bạn có thể viết một chức năng như sau:

public <KeyType, ValueType> KeyType first(LinkedHashMap<KeyType, ValueType> map) { 
    assert !map.isEmpty(); 
    return map.iterator().next(); 
} 

sẽ cung cấp cho bạn phần tử đầu tiên. Chỉ cần đảm bảo đồng bộ hóa một cách thích hợp.

Hoặc, bạn có thể xem xét chỉ lưu trữ cặp khóa/giá trị bên trong một Queue bằng cách xác định lớp trợ giúp Pair và sau đó lưu trữ Pair s trong hàng đợi.

Hy vọng điều này sẽ hữu ích!

+0

Nice, nên anh sẽ chỉ cần một số SyncObject để tín hiệu khi có thể đọc từ LinkedHashMap ở phía người tiêu dùng. –

+0

Xin chào, LinkedHashMap không phải là chủ đề an toàn và nó không thuộc loại Queue. – sperumal

+0

@ sperumal- Tôi chưa từng nói rằng một trong hai trường hợp này là như vậy. Tôi giả định rằng OP sẽ cung cấp mã đồng bộ hóa. Ngoài ra, tôi không tin rằng có bất kỳ yêu cầu nào mà nó phải thuộc loại 'Queue'; câu hỏi của OP không bao giờ đề cập đến điều này. Nếu đây là một yêu cầu, thì cách tiếp cận này chắc chắn sẽ không hoạt động. – templatetypedef

4

Tôi đề nghị bạn tạo một Queue của entrySet -

Queue<EntrySet<String,String>> queue = new SynchronousQueue<EntrySet<String,String>>(); 
for (EntrySet<String,String> entry:map.entrySet()) { 
    queue.add(entry); 
} 

Bạn có thể xem xét sử dụng một loại hàng đợi, cho phép bạn đặt các yếu tố, và chỉ chờ đợi prdocuer trong trường hợp không có sản phẩm nào như LinkedBlockingQueue.
Sau đó, nhà sản xuất có thể định lại bản đồ dựa trên các đối tượng EntrySet, nếu cần.

+0

Hmm này có vẻ như là một phương pháp tốt. Cảm ơn bạn tôi sẽ thử. Một câu hỏi là chủ đề này có an toàn không? –

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