Veelvoorkomende valkuilen
Volgorde, boxing en de common pool
Veelvoorkomende valkuilen is een gratis Java Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Java Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Java Academy bevat in totaal 4 lessen.
Parallelle uitvoering maakt niet automatisch sneller
parallel() toevoegen kan code trager maken in plaats van sneller. In deze les leer je de klassieke valkuilen, zodat je ze kunt vermijden.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long sum = IntStream.rangeClosed(1, 1_000_000).parallel()
.asLongStream().sum();
System.out.println(sum);
}
}Valkuil: extra kosten van ordening
Geordende bewerkingen zoals forEachOrdered of limit vereisen afstemming tussen threads, waardoor de voordelen van parallelle uitvoering kleiner worden.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
IntStream.rangeClosed(1, 5).parallel()
.forEachOrdered(System.out::println);
}
}unordered kan helpen
Als de volgorde niet belangrijk is, zorgt het aanroepen van unordered() ervoor dat de runtime ordeningswerk kan overslaan en vrijer kan parallelliseren.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long count = IntStream.rangeClosed(1, 1_000_000).parallel()
.unordered()
.filter(n -> n % 5 == 0)
.count();
System.out.println(count);
}
}Valkuil: verborgen boxing
Het gebruik van Stream<Integer> in parallelle uitvoering vermenigvuldigt de kosten van boxing over meerdere threads. Geef voor numeriek parallel werk de voorkeur aan streams met primitieve waarden.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long sum = IntStream.rangeClosed(1, 1_000_000).parallel().asLongStream().sum();
System.out.println(sum);
}
}Valkuil: de gedeelde common pool
Alle parallelle streams delen één ForkJoinPool.commonPool(). Een lange parallelle taak kan andere taken in dezelfde JVM uithongeren, inclusief andere delen van je toepassing.
import java.util.concurrent.ForkJoinPool;
public class Main {
public static void main(String[] args) {
System.out.println(ForkJoinPool.commonPool().getParallelism());
}
}Werk isoleren in een aangepaste pool
Om zwaar werk uit de gedeelde pool te houden, dien je de parallelle stream in binnen je eigen ForkJoinPool.
import java.util.concurrent.ForkJoinPool;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) throws Exception {
ForkJoinPool pool = new ForkJoinPool(2);
long sum = pool.submit(() ->
IntStream.rangeClosed(1, 1_000_000).parallel().asLongStream().sum()
).get();
pool.shutdown();
System.out.println(sum);
}
}Valkuil: slecht splitsbare bronnen
LinkedList, Stream.iterate en BufferedReader.lines kunnen slecht worden gesplitst. Ze parallelliseren levert vaak weinig of zelfs een negatief voordeel op.
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
long n = Stream.iterate(1, x -> x + 1)
.limit(100_000)
.parallel()
.filter(x -> x % 2 == 0)
.count();
System.out.println(n);
}
}Valkuil: lambdas met toestand
Lambdas die externe toestand lezen of schrijven, gedragen zich niet-deterministisch in parallelle uitvoering. Houd ze toestandsloos voor consistente resultaten.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int sum = IntStream.rangeClosed(1, 100).parallel()
.map(n -> n + 1)
.sum();
System.out.println(sum);
}
}Valkuil: findFirst versus findAny
findFirst moet de volgorde respecteren, wat in parallelle uitvoering extra kosten veroorzaakt. Als elk overeenkomend element voldoet, gebruik je findAny.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int found = IntStream.rangeClosed(1, 1_000_000).parallel()
.filter(n -> n % 99991 == 0)
.findAny()
.getAsInt();
System.out.println(found);
}
}Valkuil: goedkope bewerkingen op kleine gegevensverzamelingen
Bij zeer kleine verzamelingen of triviaal werk zijn de extra kosten van splitsen en samenvoegen veel groter dan elk voordeel. Blijf sequentieel werken.
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> small = List.of(1, 2, 3, 4);
int sum = small.stream().mapToInt(Integer::intValue).sum();
System.out.println(sum);
}
}Valkuil: dure samenvoeging in collectors
Collectors met dure samenvoegstappen, zoals het opbouwen van grote gesorteerde structuren, kunnen de voordelen van parallelle uitvoering tenietdoen. Eenvoudige accumulaties worden goedkoop samengevoegd.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long total = IntStream.rangeClosed(1, 1_000_000).parallel()
.mapToLong(n -> n)
.sum();
System.out.println(total);
}
}Korte controle
Waarom kan findFirst trager zijn dan findAny op een parallelle stream?
Samenvatting
Je hebt de meest voorkomende valkuilen van parallelle uitvoering geleerd:
- Ordening (
forEachOrdered,limit,findFirst) brengt extra afstemmingskosten met zich mee; gebruik waar mogelijkunorderedoffindAny. - Boxing vermenigvuldigt de kosten; geef de voorkeur aan streams met primitieve waarden.
- De gedeelde pool kan andere taken uithongeren; isoleer zwaar werk in een aangepaste
ForkJoinPool. - Slecht splitsbare bronnen, kleine gegevensverzamelingen en dure samenvoegingen ondermijnen allemaal parallellisme.
Leer Java met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 104
- Lessen
- 374
Veelgestelde vragen
Is de les “Veelvoorkomende valkuilen” gratis?
Ja — de volledige tekst van “Veelvoorkomende valkuilen” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Java Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Java Academy bevat in totaal 4 lessen.
Wat leer ik in “Veelvoorkomende valkuilen”?
Volgorde, boxing en de common pool Je oefent met Java Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Java Academy te beginnen?
Ervaring vooraf is niet nodig. Java Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.
Hoe lang duurt de les “Veelvoorkomende valkuilen”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Java Academy?
Ja. Elke les over Java Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Parallelle streams maken
- Wanneer parallellisme helpt
- Threadveiligheid en bijwerkingen
- Veelvoorkomende valkuilen