2017-11-23 25 views
2

저는 ConcurrentLinkedQueue를 가지고 있으며 두 개의 반으로 나눠서 두 개의 개별 스레드가 각각을 처리하도록하고 싶습니다. Spliterator를 사용하여 시도했지만 분할 된 큐를 가져 오는 방법을 이해하지 못합니다. Spliterator를 사용하여 ConcurrentLinkedQueue를 반으로 나누십시오.

ConcurrentLinkedQueue<int[]> q = // contains a large number of elements 
Spliterator<int[]> p1 = q.spliterator(); 
Spliterator<int[]> p2 = p1.trySplit(); 
p1.getQueue(); 
p2.getQueue(); 

내가 원하는하지만 등 p1.getQueue()

은 내가 그것을 할 수있는 올바른 방법을 알려 주시기 바랍니다 할 수 없습니다.

+1

Spliterator를 사용하여 대기열을 두 개의 대기열로 분할 할 수 없습니다. – immibis

답변

4

일반적으로 반으로 분할 할 수 없습니다. 절반으로 나누면이 큐는 각 시점마다 크기가 있어야합니다. 그리고 CLQ에는 size() 메서드가 있지만,이 크기는 탐색 시간이 O(n)이고이 값이 concurrent queue이므로 크기가 정확하지 않을 수도 있습니다. 이유는 결국 concurrent입니다. 현재 SpliteratorCLQ에서 볼 수있는 일괄 처리로 분할됩니다.

당신이 요소를 논리적으로 반으로 분할하고 처리 할 경우에, 나는 훨씬 분할하는 drainTo 방법이 몇 가지 Blocking 구현, 당신은 예를 들어 ArrayList의 요소를 배출 할 수 이러한 방법으로, 이동 제안 더 나은 (반반, 반반 등).

왜 다른 스레드에서 처리를 수행 하시겠습니까? ? 이것은 매우 반 직관적 인 것처럼 보입니다. Spliterator은 병렬 스트림에서 작동하도록 설계되었습니다. trySplit을 한 번으로 호출하는 것만으로는 충분하지 않습니다. null이 반환 될 때까지 호출해야합니다.이 중 하나를 수행하는 것은 나에게 매우 나쁜 생각처럼 들릴 수 있습니다.

+1

'null '을 반환 할 때까지 호출 할 필요가 없습니다. 논리가 더 복잡합니다. 그러나 한 번 호출하는 것은 실제로 충분하지 않습니다. 특히 소스가 'ConcurrentLinkedQueue'인 경우에는 충분하지 않습니다. – Holger

+0

@Holger 나는 이것이 동시적인 구조라는 사실과 관련이 없다고 생각한다. 맞습니까? – Eugene

+2

이미 문제를 잘 설명 했으므로 동시 적이며 링크되어있어 "올바른"개수의 요소를 분리 할 수있는 쉬운 방법이 없으므로 첫 번째 분할을위한 작은 버퍼로 구현이 시작되어 버퍼 크기가 각각의 후속 분할 때문에 정말 큰'ConcurrentLinkedQueue'를 위해 진정한 절반 가까이에 도착하기 전에'trySplit' 호출을 조용하게해야합니다. – Holger