2017-05-20 6 views
5

입력을 가져 와서 병렬 스트림을 적용하려면 출력을 목록으로 원합니다. 입력은 우리가 스트림을 적용 할 수있는 모든 목록 또는 컬렉션 일 수 있습니다. java 8의 병렬 스트림에서 수집

여기 내 문제

는 우리가 그들을지도로 출력을 원한다면 우리는 자바에서 옵션이

list.parallelStream().collect(Collectors.toConcurrentMap(args)) 

처럼하지만에 스레드 안전한 방법으로 병렬 스트림에서 수집 볼 수있는 옵션이없는 가지고있다 출력으로서리스트를 제공한다. 내가 거기에 또 하나의 옵션은 우리가 수집 방법의 다양한 동시 구현을 제공 할 수있는이 방법으로

list.parallelStream().collect(Collectors.toCollection(<Concurrent Implementation>))

을 사용하십시오. 하지만 CopyOnWriteArrayList List 구현 만 java.util.concurrent에 있다고 생각합니다. 여기에 다양한 대기열 구현을 사용할 수 있지만 목록과 다를 수 있습니다. 여기서 내가 의미하는 바는 우리가 목록을 얻기위한 해결 방법이 될 수 있다는 것입니다.

출력을 목록으로 원하면 가장 좋은 방법은 무엇인지 안내해주세요.

참고 : 이와 관련된 다른 게시물을 찾을 수 없으므로 참조가 도움이됩니다.

+1

'Collections.synchronizedList (새 ArrayList <>())'를 전달할 수 없습니까? –

+3

@ OleV.V. 필요 없음. Collection 객체는 스레드로부터 안전 할 필요는 없습니다. – Andreas

답변

7

수집되는 데이터를 수신하는 데 사용되는 Collection 개체는 병행 할 필요가 없습니다. 간단한 ArrayList을 제공 할 수 있습니다.

병렬 스트림의 값 모음이 실제로 Collection 개체로 수집되지 않았기 때문입니다. 각 스레드는 자신의 데이터를 수집하고 모든 하위 결과는 인 단일 최종 Collection 개체로 병합됩니다.

이는 모든 Collector의 javadoc에 잘 문서화 및 Collector 당신이 (가) collect() 방법을 제공하고있는 매개 변수입니다 :

<R,A> R collect(Collector<? super T,A,R> collector) 
+0

나는 그 부분을 놓쳤다 고 생각한다.나의 초기 이해는 우리가 지나가는 컬렉션은 오직 하나의 것으로 만 수집한다는 것이다. 하지만 지금 제 질문은 그때 왜 우리가 'Collectors.toConcurrentMap'을 필요로하는지 간단한 해시 맵을 사용한 다음 다시 결합 할 수 있다는 것입니다. –

+2

@VipulGoyal 이것은 분명히 최적화 목적을위한 것입니다. 커다란'HashMap'을 병합하는 것은 꽤 비쌀 수 있습니다. ConcurrentHashMap은 스트림을 구현할 때 이미 존재했기 때문에 그냥 사용하지 않는 것이 좋을까요? – Eugene

+0

@Eugene 'HashMap'을 병합하는 것이 비용이 많이 든다는 것에 동의합니다. 하지만 지금 내가 생각하고있는 것은 동시성 목록에 대한 더 나은 구현이 없다는 것입니다. 그렇다면'CopyOnWriteArrayList' 이외에는 꽤 비쌉니다. 그곳에서의 도전은 무엇입니까, 아니면 무엇인가 놓치고 있습니까? 어쨌든 나는 함께 모든 것이 다른 토론이라는 나의 대답을 얻었다. –

4

But there is no option that I can see to collect from parallel stream in thread safe way to provide list as output. 이것은 완전히 잘못된 것입니다.

스트림의 전체적인 점은 스레드로부터 안전하지 않은 Collection을 사용하여 완벽하게 유효한 스레드 안전 결과를 얻을 수 있다는 점입니다. 이는 스트림이 구현되는 방식 때문입니다 (그리고 이것은 스트림 디자인의 핵심 부분이었습니다). Collector은 각 단계에서 새 인스턴스를 생성하는 supplier 메서드를 정의합니다. 이러한 인스턴스는 둘 사이에 병합됩니다.

Stream.of(1,2,3,4).parallel() 
      .collect(Collectors.toList()); 

스트림 4 개 요소가 있기 때문에, 하나의 결과로 끝 병합한다 작성된 ArrayList 4 개 경우가있을 것이다 (최소한 가정 :

그래서이 완벽 스레드 안전 4 CPU 코어)

toConcurrent과 같은 다른 방법에서는 단일 결과 컨테이너을 생성하고 모든 스레드가 결과를 넣습니다.

+0

... 최소한 4 개의 CPU 코어가 있다고 가정합니다. – Holger

+0

@Holger 세부 사항에 세심한주의를 기울이기 위해 노력하고 있지만, 그 이상입니다. – Eugene