Brugerdefinerede trådpuljer i Java 8 parallelle streams

1. Oversigt

Java 8 introducerede konceptet med Stråde som en effektiv måde at udføre bulkoperationer på data på. Og parallelt Strømme kan opnås i miljøer, der understøtter samtidighed.

Disse streams kan leveres med forbedret ydeevne - på bekostning af multi-threading overhead.

I denne hurtige vejledning ser vi på en af ​​de største begrænsninger af Strøm API og se hvordan man får en parallel stream til at arbejde med en brugerdefineret TrådPool eksempel, alternativt - der er et bibliotek, der håndterer dette.

2. Parallel Strøm

Lad os starte med et simpelt eksempel - at kalde parallelStream metode på nogen af Kollektion typer - som vil returnere en muligvis parallel Strøm:

@Test offentlig ugyldighed givenList_whenCallingParallelStream_shouldBeParallelStream () {List aList = new ArrayList (); Stream parallelStream = aList.parallelStream (); assertTrue (parallelStream.isParallel ()); }

Standardbehandlingen, der forekommer i en sådan Strøm bruger ForkJoinPool.commonPool (),-en Trådbassin deles af hele applikationen.

3. Brugerdefineret Trådbassin

Vi kan faktisk passere en brugerdefineret TrådPool ved behandling af strøm.

Det følgende eksempel kan have en parallel Strøm brug en brugerdefineret Trådbassin at beregne summen af ​​lange værdier fra 1 til 1.000.000 inklusive:

@Test offentlig ugyldighed giveRangeOfLongs_whenSummedInParallel_shouldBeEqualToExpectedTotal () kaster InterruptedException, ExecutionException {long firstNum = 1; lang lastNum = 1_000_000; Liste aList = LongStream.rangeClosed (firstNum, lastNum) .boxed () .collect (Collectors.toList ()); ForkJoinPool customThreadPool = ny ForkJoinPool (4); long actualTotal = customThreadPool.submit (() -> aList.parallelStream (). reducer (0L, Long :: sum)). get (); assertEquals ((lastNum + firstNum) * lastNum / 2, actualTotal); }

Vi brugte ForkJoinPool konstruktør med et parallelitetsniveau på 4. Nogle eksperimenter er nødvendige for at bestemme den optimale værdi for forskellige miljøer, men en god tommelfingerregel er simpelthen at vælge antallet baseret på hvor mange kerner din CPU har.

Dernæst behandlede vi indholdet af parallel Strøm, opsummerer dem i reducere opkald.

Dette enkle eksempel viser muligvis ikke den fulde nytte af at bruge en brugerdefineret Trådbassin, men fordelene bliver tydelige i situationer, hvor vi ikke ønsker at binde det fælles Trådbassin med langvarige opgaver (f.eks. behandling af data fra en netværkskilde) eller det fælles Trådbassin bruges af andre komponenter i applikationen.

4. Konklusion

Vi har kort set på, hvordan man kører en parallel Strøm ved hjælp af en brugerdefineret Trådbassin. I det rigtige miljø og med korrekt brug af parallelismeniveauet kan præstationsgevinster opnås i visse situationer.

De komplette kodeeksempler, der henvises til i denne artikel, kan findes på Github.