2013-10-04 7 views
10

Potrzebuję mieć bezpieczną dla wątków strukturę LIFO i stwierdziłem, że mogę używać do tego wątkowych implementacji Deque. Java 7 wprowadziła ConcurrentLinkedDeque, a Java 6 ma LinkedBlockingDeque.ConcurrentLinkedDeque vs LinkedBlockingDeque

Gdybym stosować wyłącznie metody non-blocking w LinkedBlockingDeque takich jak addFirst() i removeFirst() to ma żadnej różnicy ConcurrentLinkedDeque?

tj. Jeśli pominiesz aspekt blokowania, czy istnieje inna różnica między ConcurrentLinkedDeque i LinkedBlockingDeque, z wyjątkiem LinkedBlockingDeque, która jest ograniczona?

+0

Czy zapoznałeś się z implementacją obu? Jakie są twoje kryteria, w przypadku, gdy podejmowałbyś decyzję dla jednej nad drugą? Wydajność? MemoryOverhead? – Fildor

+0

Po prostu chciałem wiedzieć, co jest stracone, jeśli zostałem z Javą 6 i użyłem LinkedBlockingDeque – Nufail

Odpowiedz

5

dwie rzeczy:

1: Gdybym stosować wyłącznie metody non-blocking w LinkedBlockingDeque takich jak addFirst() i removeFirst() to ma żadnej różnicy ConcurrentLinkedDeque?

Te metody mają znaczenie, jeśli chodzi o jednoczesnym zachowaniu ryglowania, LinkedBlockingDeque:

public E removeFirst() { 
     E x = pollFirst(); 
     .. 
    } 
public E pollFirst() { 
     lock.lock(); //Common lock for while list 
     try { 
      return unlinkFirst(); 
     } finally { 
      lock.unlock(); 
     } 
    } 

Podobnie do addFirst metodą. W przypadku ConcurrentLinkedDeque to zachowanie blokujące dla obu metod jest inne i jest bardziej wydajne, ponieważ nie blokuje całej listy, ale jej podzbiór sprawdzający źródło dla ConcurrentLinkedDeque da ci większą jasność.

2: Z javadoc z ConcurrentLinkedDeque:

Pamiętaj, że w przeciwieństwie do większości kolekcji, metoda rozmiar nie jest operacją stały etat.

..

Dodatkowo, większość operacji AddAll, removeAll, retainAll, containsAll równa i toArray nie gwarantują przeprowadzić atomowo.

powyżej nie jest prawdziwe dla LinkedBlockingDeque

4

ConcurentLinkedDequeue jest blokowany (patrz komentarze w kodzie źródłowym), podczas gdy LinkedBlockingQueue używa blokowania. Że jest byłym ma być bardziej wydajny

9

Aby zacytować wielkiego Doug Lea (podkreślenie moje)

LinkedBlockingDeque vs ConcurrentLinkedDeque

Klasa LinkedBlockingDeque ma być „standard” blokowanie deque klasa. Obecna implementacja ma względnie niską narzutę, ale stosunkowo niską skalowalność. ...

... ConcurrentLinkedDeque ma prawie odwrotny profil wydajność jak LinkedBlockingDeque: stosunkowo wysokim obciążeniu, ale bardzo dobra skalowalność. ... we współbieżnych aplikacjach nie jest tak powszechne, aby chcieć Deque, które jest bezpieczne dla wątków, ale nie obsługuje blokowania. A większość tych, którzy tak robią, jest prawdopodobnie lepsza dzięki rozwiązaniom specjalnym.

Wydaje się sugerować, że powinieneś używać LinkedBlockingDeque, chyba że potrzebujesz funkcji ConcurrentLinkedDeque.

+1

Pamiętaj jednak, że powiedział to nieoficjalnie iw 2004 roku. – kervin

1

Pierwszą rzeczą zarówno LinkedBlockingDeque i ConcurrentLinkedDeque oba są bezpieczne wątek, ale który z nich korzystać, zależy od wymagań aplikacji.

Na przykład

LinkedBlockingDequeue: Użyj tej kolekcji, jeśli chcesz, że w danym momencie tylko pojedynczy wątek może operować na danych, a kiedy trzeba blokowanie dla danej aplikacji.

ConcurrentLinkedDeque: Jest to również bezpieczeństwo wątków deque kolekcja, jeśli aplikacja jest wielo gwintowane i chcesz aby każdy z Twojego wątku może uzyskać dostęp do danych, a następnie ConcurrentLinkedDequeue jest najlepszym wyborem dla niego.

Jak w swoim pytaniu,

1. Muszę mieć strukturę LIFO wątek bezpieczny,

Zastosowanie LinkedBlockingDeque jeśli w danej chwili chcesz tylko pojedynczy wątek może obsługiwać dane.

Zastosowanie ConcurrentLinkedDeque jeśli chcesz, aby każdy wątek może uzyskać dostęp do udostępnionych danych

2. Jeśli pominąć aspekt blokowania, czy istnieje jakakolwiek inna różnica między ConcurrentLinkedDeque i LinkedBlockingDeque,

Tak, istnieje różnica, ponieważ LinkedBlockingDeque używa mechanizmu blokującego, a ConcurrentLinkedDeque nie wpływa na wydajność, gdy chcesz operować danymi.