2016-11-10 39 views
6

Scenariusz: Mój producent wypełnia tablicę, powiedzmy, pojemność nowy, [10], zanim mój konsument będzie miał szansę go wykorzystać. Mój producent widzi, że tablica jest pełna i blokuje.W jaki sposób ArrayBlockingQueue unika tasowania elementów tablicy?

Następnie mój konsument przychodzi i usuwa int [0], i sygnalizuje producentowi, że tablica ma teraz puste miejsce do wypełnienia.

Mój producent budzi się i próbuje dodać nowy element do tablicy. Biorąc pod uwagę, że tylko int [0] jest bezpłatne, a my wdrażamy FIFO, czy ArrayBlockingQueue przetasuje wszystkie pozostałe 9 elementów po lewej stronie, wypełniając 0-8 indeksów i pozostawiając int [9] za darmo dla producenta?

Szukałem w realizacji, ale nie widzę żadnych funkcji array kopiowania

Odpowiedz

5

No kopiowanie elementów tablicy jest wykonywana, ponieważ ArrayBlockingQueue wykorzystuje tablicę jako bufora kołowego. Utrzymuje dwa indeksy: takeIndex i putIndex i otacza je, gdy dotrą do końca tablicy.

Po operacji, która dodaje lub bierze element wywołuje prywatny „przyrost” metodę zwaną inc, która otacza indeks wokół końca:

final int inc(int i) { 
    return (++i == items.length)? 0 : i; 
} 

Oto przykład, jak ta metoda jest stosowana:

private void insert(E x) { 
    items[putIndex] = x; 
    putIndex = inc(putIndex); // <<== Wraps around 
    ++count; 
    notEmpty.signal(); 
} 
+0

Jak bardzo sprytnie. – TheCoder

0

ArrayBlockingQueue utrzymać dwie zmienne przypuszczać frontIndex i rearIndex obsłużyć to zamiast przesuwania el ementów. Jeśli kolejka jest pełna. a każdy element jest wypychany przez konsumenta, z indeksem A [0] następnie rearIndex przeniesiono do wskaźnika Następnym razem, gdy producent próbuje dodać dowolny element frontIndex zostanie przeniesiony do indeksu po indeksie . a następna operacja zostanie wykonana na a [0].

Tutaj FrontIndex == RearIndex oznacza, że ​​kolejka jest pełna.