Rinnakkaisvirta-API
Olet todennäköisesti jo tuttu Stream API:n, sen metodien ja toimintaperiaatteen kanssa (jos et ole, opiskele tämä aihe ja palaa sitten tähän lukuun).
Tavallinen tietovirta ei ole rinnakkainen, eli vaikka se olisi kuinka kätevä ja selkeä koodissa, Stream API:n käyttö ilman parallelStream()-metodia voi suurten tietomäärien kanssa vaikuttaa merkittävästi suorituskykyyn.
On olemassa myös parallel()-metodi, jota voidaan käyttää muuntamisen jälkeen streamiksi.
List<Integer> result = list.stream().parallel()
.map(num -> ++num)
.toList();
Erona on, että parallelStream() luo rinnakkaisvirran suoraan kokoelmasta, kun taas parallel() muuntaa olemassa olevan sarjallisen virran rinnakkaisvirraksi.
Ja ennen kaikkea, meidän ohjelmoijien ei tarvitse tehdä mitään muuta kuin vaihtaa stream()-metodi parallelStream()-metodiin. Stream API hoitaa kaiken itse ja optimoi ohjelmamme!
Esimerkki: Lukulistan käsittely
Oletetaan, että meillä on lista numeroita ja haluamme laskea kaikkien listan numeroiden neliöiden summan.
Main.java
123456789101112131415161718192021222324252627package com.example; import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of integers List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // Sequential stream to sum the squares of numbers int sumSequential = numbers.stream() // Create a sequential stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the sequential sum System.out.println("Sum of squares (sequential): " + sumSequential); // Parallel stream to sum the squares of numbers int sumParallel = numbers.parallelStream() // Create a parallel stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the parallel sum System.out.println("Sum of squares (parallel): " + sumParallel); } }
Kuten huomaat, korvasimme vain stream()-kutsun parallelStream()-kutsulla JA SE ON KAIKKI. Tässä esimerkissä siitä ei ole hyötyä, koska yksisäikeisessä ympäristössä 10 merkin taulukko suoritetaan nopeammin. Tämä johtuu siitä, että Stream API:n toteutus tekee paljon toimenpiteitä jakaakseen tehtävän säikeiden kesken.
Stream API päättää myös itse, kuinka monta säiettä se käyttää tähän tehtävään, jotta suorituskyky olisi mahdollisimman tehokas.
Miten se toimii taustalla:
1. Rinnakkaisvirran luominen: Kun kutsutaan parallelStream(), Java luo rinnakkaisvirran alkuperäisen tietolähteen perusteella;
2. ForkJoinPoolin käyttö (tarkastellaan myöhemmin): Rinnakkaisvirrat käyttävät yhteistä säieallasta, ForkJoinPool.commonPool(), joka hallinnoi joukkoa työntekijäsäikeitä;
3. Jakaminen: Tieto rinnakkaissäikeessä jaetaan osiin käyttämällä Spliterator-rajapintaa;
4. Käsittely: Jokainen työntekijäsäie ForkJoinPool käsittelee oman osuutensa tiedoista;
5. Yhdistäminen: Tietojen käsittelyn jälkeen työntekijäsäikeet yhdistävät tulokset.
Rinnakkaisvirtojen edut
Suorituskyvyn kasvu on yksi rinnakkaissäikeiden tärkeimmistä eduista, sillä ne mahdollistavat tehtävien jakamisen useille säikeille, mikä nopeuttaa käsittelyä moniydinsuorittimilla.
Lisäksi rinnakkaissäikeiden API:n helppokäyttöisyys tekee niiden integroinnista olemassa olevaan koodiin yksinkertaista, eikä monimutkaista säikeiden hallintaa tarvita.
Lisäksi skaalautuvuus on merkittävä etu, sillä rinnakkaissäikeet mukautuvat automaattisesti käytettävissä olevien prosessoriydinten määrään, optimoiden tehtävien suorittamisen tehokkaasti.
1. Mitä luokkaa rinnakkaiset säikeet käyttävät säikeiden hallintaan?
2. Mitä metodia käytetään rinnakkaisvirran luomiseen?
3. Mitä Spliterator-rajapinta tekee rinnakkaisvirtojen yhteydessä?
Kiitos palautteestasi!
Kysy tekoälyä
Kysy tekoälyä
Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme
Awesome!
Completion rate improved to 3.33
Rinnakkaisvirta-API
Pyyhkäise näyttääksesi valikon
Olet todennäköisesti jo tuttu Stream API:n, sen metodien ja toimintaperiaatteen kanssa (jos et ole, opiskele tämä aihe ja palaa sitten tähän lukuun).
Tavallinen tietovirta ei ole rinnakkainen, eli vaikka se olisi kuinka kätevä ja selkeä koodissa, Stream API:n käyttö ilman parallelStream()-metodia voi suurten tietomäärien kanssa vaikuttaa merkittävästi suorituskykyyn.
On olemassa myös parallel()-metodi, jota voidaan käyttää muuntamisen jälkeen streamiksi.
List<Integer> result = list.stream().parallel()
.map(num -> ++num)
.toList();
Erona on, että parallelStream() luo rinnakkaisvirran suoraan kokoelmasta, kun taas parallel() muuntaa olemassa olevan sarjallisen virran rinnakkaisvirraksi.
Ja ennen kaikkea, meidän ohjelmoijien ei tarvitse tehdä mitään muuta kuin vaihtaa stream()-metodi parallelStream()-metodiin. Stream API hoitaa kaiken itse ja optimoi ohjelmamme!
Esimerkki: Lukulistan käsittely
Oletetaan, että meillä on lista numeroita ja haluamme laskea kaikkien listan numeroiden neliöiden summan.
Main.java
123456789101112131415161718192021222324252627package com.example; import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { // Create a list of integers List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // Sequential stream to sum the squares of numbers int sumSequential = numbers.stream() // Create a sequential stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the sequential sum System.out.println("Sum of squares (sequential): " + sumSequential); // Parallel stream to sum the squares of numbers int sumParallel = numbers.parallelStream() // Create a parallel stream from the list .mapToInt(n -> n * n) // Map each number to its square .sum(); // Sum the squares // Print the result of the parallel sum System.out.println("Sum of squares (parallel): " + sumParallel); } }
Kuten huomaat, korvasimme vain stream()-kutsun parallelStream()-kutsulla JA SE ON KAIKKI. Tässä esimerkissä siitä ei ole hyötyä, koska yksisäikeisessä ympäristössä 10 merkin taulukko suoritetaan nopeammin. Tämä johtuu siitä, että Stream API:n toteutus tekee paljon toimenpiteitä jakaakseen tehtävän säikeiden kesken.
Stream API päättää myös itse, kuinka monta säiettä se käyttää tähän tehtävään, jotta suorituskyky olisi mahdollisimman tehokas.
Miten se toimii taustalla:
1. Rinnakkaisvirran luominen: Kun kutsutaan parallelStream(), Java luo rinnakkaisvirran alkuperäisen tietolähteen perusteella;
2. ForkJoinPoolin käyttö (tarkastellaan myöhemmin): Rinnakkaisvirrat käyttävät yhteistä säieallasta, ForkJoinPool.commonPool(), joka hallinnoi joukkoa työntekijäsäikeitä;
3. Jakaminen: Tieto rinnakkaissäikeessä jaetaan osiin käyttämällä Spliterator-rajapintaa;
4. Käsittely: Jokainen työntekijäsäie ForkJoinPool käsittelee oman osuutensa tiedoista;
5. Yhdistäminen: Tietojen käsittelyn jälkeen työntekijäsäikeet yhdistävät tulokset.
Rinnakkaisvirtojen edut
Suorituskyvyn kasvu on yksi rinnakkaissäikeiden tärkeimmistä eduista, sillä ne mahdollistavat tehtävien jakamisen useille säikeille, mikä nopeuttaa käsittelyä moniydinsuorittimilla.
Lisäksi rinnakkaissäikeiden API:n helppokäyttöisyys tekee niiden integroinnista olemassa olevaan koodiin yksinkertaista, eikä monimutkaista säikeiden hallintaa tarvita.
Lisäksi skaalautuvuus on merkittävä etu, sillä rinnakkaissäikeet mukautuvat automaattisesti käytettävissä olevien prosessoriydinten määrään, optimoiden tehtävien suorittamisen tehokkaasti.
1. Mitä luokkaa rinnakkaiset säikeet käyttävät säikeiden hallintaan?
2. Mitä metodia käytetään rinnakkaisvirran luomiseen?
3. Mitä Spliterator-rajapinta tekee rinnakkaisvirtojen yhteydessä?
Kiitos palautteestasi!