2013-06-12 27 views
17

Tôi nghĩ rằng, trong hầu hết các trường hợp, ArrayBlockingQueue sẽ hoạt động tốt hơn so với LinkedBlockingQueue. Tuy nhiên, đó là trường hợp khi luôn có đủ chỗ trong mảng ... Nếu nó đầy, không thể dự đoán được liệu nó có hoạt động tốt hay không, vì nó sẽ chặn luồng đang cố đẩy dữ liệu vào hàng đợi .. .Java: ArrayBlockingQueue vs. LinkedBlockingQueue

Vì vậy, câu hỏi của tôi là: Có triển khai thực hiện trung gian nào là BlockingQueue không? Giả sử, một số ArrayListBlockingQueue hoặc BucketListBlockingQueue? Một cái gì đó giống như một danh sách các mảng, để hàng đợi có thể tăng công suất động, trong khi vẫn có lợi ích hợp lý từ việc sử dụng mảng để lưu trữ dữ liệu cuối cùng?

+0

Danh sách mảng sẽ không cải thiện hiệu suất ... Tại sao phải không? Và bên cạnh đó: tại sao bạn lo lắng về hiệu suất? Bạn có thực sự có vấn đề? Bạn có hồ sơ? – Dariusz

+0

Tôi đang nghĩ về địa phương bộ nhớ. Nếu bạn sử dụng danh sách được liên kết có các yếu tố nhảy xung quanh các địa chỉ bộ nhớ ngẫu nhiên, bạn sẽ dễ bị mất bộ nhớ cache và các vấn đề tương tự.Thêm vào đó, để lấy từ bộ nhớ, bạn phải lấy địa chỉ của phần tử tiếp theo, rồi lấy nội dung của địa chỉ đó ... Trong khi đó, với một mảng, bạn chỉ cần làm địa chỉ ++ để lấy địa chỉ của phần tử tiếp theo. Với một danh sách các mảng, bạn sẽ có một số thỏa hiệp giữa hai việc triển khai ... Bạn có nghĩ khác không? –

+1

Tôi nghĩ rằng một danh sách các mảng cung cấp cho bạn những lợi thế từ cả hai bộ sưu tập gốc. Bạn vẫn phải phân bổ bộ nhớ và, tùy thuộc vào kích thước của mảng, nó sẽ bị phân mảnh nhiều hơn hoặc ít hơn. Tôi nghĩ rằng nếu bạn làm cho thuật toán thay đổi kích thước bộ sưu tập dựa trên Array của bạn, bạn sẽ có vài thay đổi kích thước và lặp lại rất nhanh. Đối với bộ nhớ cục bộ - các bộ sưu tập lưu trữ các tham chiếu đến các đối tượng và các đối tượng đó có thể được đặt ở bất kỳ vị trí nào trong bộ nhớ, vì vậy bạn có thể sẽ không nhận được lợi ích từ việc sử dụng một bộ sưu tập này. – Dariusz

Trả lời

6

My 2 cents:

Để bắt đầu, điểm mấu chốt ở đây là bạn không thực sự quan tâm về sự khác biệt ở đây bởi vì ngay cả khi bạn đang sử dụng một LinkedBlockingQueue đơn giản, hiệu suất là đủ tốt khi bạn đang phân phối một số hệ thống cấp micro giây. Vì vậy, sự khác biệt về hiệu suất ở đây không thực sự tuyệt vời như vậy.

Nếu bạn đang viết hệ thống hiệu suất cao quan trọng và bạn đang sử dụng hàng đợi để truyền thông điệp giữa các chủ đề, bạn luôn có thể ước tính kích thước hàng đợi cần thiết cho [Queue Size] = [Max accept delay] * [Max message rate ]. Bất cứ điều gì có thể phát triển vượt quá khả năng như vậy có nghĩa là bạn bị một vấn đề người tiêu dùng chậm. Trong một ứng dụng quan trọng của nhiệm vụ, sự chậm trễ như vậy có nghĩa là hệ thống của bạn đang hoạt động sai. Một số quy trình thủ công có thể cần thiết để đảm bảo hệ thống đang chạy đúng cách.

Trong trường hợp hệ thống của bạn không phải là nhiệm vụ quan trọng, bạn có thể chỉ cần tạm dừng (chặn) nhà xuất bản cho đến khi một số người tiêu dùng có sẵn.

14

1. LinkedBlockingQueue (Thực hiện LinkedList nhưng không chính xác JDK Thực hiện LinkedList Nó sử dụng tĩnh lớp bên trong Node để duy trì Liên kết giữa các yếu tố) lớp

Constructor for LinkedBlockingQueue 
public LinkedBlockingQueue(int capacity) 
{ 
     if (capacity < = 0) throw new IllegalArgumentException(); 
     this.capacity = capacity; 
     last = head = new Node<E>(null); // Maintains a underlying linkedlist. (Use when size is not known) 
} 

Node Được sử dụng để duy trì Liên kết

static class Node<E> { 
    E item; 
    Node<E> next; 
    Node(E x) { item = x; } 
} 

2. ArrayBlockingQueue (Mảng thực hiện)

Constructor cho ArrayBlockingQueue

public ArrayBlockingQueue(int capacity, boolean fair) 
{ 
      if (capacity < = 0) 
       throw new IllegalArgumentException(); 
      this.items = new Object[capacity]; // Maintains a underlying array 
      lock = new ReentrantLock(fair); 
      notEmpty = lock.newCondition(); 
      notFull = lock.newCondition(); 
} 

IMHO khác biệt lớn nhất giữa ArrayBlockingQueue và LinkedBlockingQueue là rõ ràng từ constructor người ta cơ bản cấu trúc dữ liệu mảng và LinkedList khác.

ArrayBlockingQueue sử dụng single-lock double condition algorithm và LinkedBlockingQueue là biến thể của "hai khóa đợi" thuật toán và nó có 2 ổ khóa 2 điều kiện (takeLock, putLock)

Đến bây giờ tôi đã so sánh giữa những 2 triển khai Trở lại câu hỏi ban đầu, Câu hỏi tương tự đã được hỏi trong concurrency mailing list trong cuộc đàm phán này doug Lea về DynamicArrayBlockingQueue đó là implementation provided by Dawid Kurzyniec.

+6

Tôi thấy một phiếu giảm giá ở đây Nếu bạn không đồng ý với câu trả lời, vui lòng cung cấp bình luận cũng để tôi có thể cải thiện hoặc sửa chữa nếu có điều gì đó sai. – Vipin

+0

để rõ ràng hơn 'ArrayBlockingQueue' sử dụng' Thông tư Array' như cấu trúc cơ bản +1 cho câu trả lời –

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