Java Academy · Oppitunti

Yleiset sudenkuopat

Järjestys, boxing ja yhteinen säieallas.

Oppitunti 4/413 vaihetta

Yleiset sudenkuopat on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.

Rinnakkaisuus ei tarkoita ilmaista nopeutta

parallel()-operaation lisääminen voi hidastaa koodia nopeuttamisen sijaan. Tässä oppitunnissa käsitellään tavalliset sudenkuopat, jotta voitte välttää ne.

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);
    }
}

Sudenkuoppa: järjestyksen aiheuttama yleiskustannus

Järjestystä säilyttävät operaatiot, kuten forEachOrdered tai limit, pakottavat säikeet koordinoimaan toimintaansa, mikä heikentää rinnakkaisuuden hyötyjä.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.rangeClosed(1, 5).parallel()
            .forEachOrdered(System.out::println);
    }
}

unordered voi auttaa

Jos järjestyksellä ei ole merkitystä, unordered()-kutsulla ajonaikainen ympäristö voi ohittaa järjestykseen liittyvän työn ja rinnakkaistaa suoritusta vapaammin.

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);
    }
}

Sudenkuoppa: piilevä boxing

Stream<Integer>-tyypin käyttäminen rinnakkain moninkertaistaa boxingin kustannukset säikeiden välillä. Suosikaa numeerisessa rinnakkaistyössä primitiivivirtoja.

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);
    }
}

Sudenkuoppa: jaettu yhteinen pooli

Kaikki rinnakkaiset virrat käyttävät samaa ForkJoinPool.commonPool()-poolia. Pitkä rinnakkainen tehtävä voi estää muita saman JVM:n tehtäviä, mukaan lukien sovelluksen muut osat.

import java.util.concurrent.ForkJoinPool;

public class Main {
    public static void main(String[] args) {
        System.out.println(ForkJoinPool.commonPool().getParallelism());
    }
}

Työn eristäminen mukautettuun pooliin

Jotta raskas työ pysyy yhteisen poolin ulkopuolella, suorittakaa rinnakkainen virta oman ForkJoinPool-poolinne sisällä.

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);
    }
}

Sudenkuoppa: huonosti jaettavat lähteet

LinkedList, Stream.iterate ja BufferedReader.lines jakautuvat huonosti. Niiden rinnakkaistamisesta on usein vain vähän hyötyä tai se voi jopa heikentää suorituskykyä.

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);
    }
}

Sudenkuoppa: tilalliset lambdat

Ulkoista tilaa lukevat tai kirjoittavat lambdat toimivat rinnakkain epädeterministisesti. Pitäkää ne tilattomina, jotta saatte yhdenmukaisia tuloksia.

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);
    }
}

Sudenkuoppa: findFirst vastaan findAny

findFirst-operaation on noudatettava järjestystä, mikä lisää rinnakkaisen suorituksen kustannuksia. Jos mikä tahansa täsmäävä alkio kelpaa, käyttäkää findAny-operaatiota.

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);
    }
}

Sudenkuoppa: kevyet operaatiot pienellä datalla

Pienillä kokoelmilla tai vähäisellä työllä osiin jakamisen ja yhdistämisen yleiskustannus on paljon suurempi kuin mahdollinen hyöty. Pysykää peräkkäisessä suorituksessa.

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);
    }
}

Sudenkuoppa: kerääjien kallis yhdistäminen

Kalliin yhdistämisvaiheen sisältävät kerääjät, kuten suurten järjestettyjen rakenteiden muodostajat, voivat mitätöidä rinnakkaisuuden hyödyt. Yksinkertaiset kerrytykset yhdistyvät edullisesti.

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);
    }
}

Pikatarkistus

Miksi findFirst voi olla rinnakkaisessa virrassa hitaampi kuin findAny?

Kertaus

Opitte rinnakkaisuuden tavalliset sudenkuopat:

  • Järjestyksen säilyttäminen (forEachOrdered, limit, findFirst) lisää koordinoinnin kustannuksia; käyttäkää mahdollisuuksien mukaan unordered- tai findAny-operaatiota.
  • Boxing moninkertaistaa kustannukset; suosikaa primitiivivirtoja.
  • Jaettu yhteinen pooli voi estyä; eristäkää raskas työ mukautettuun ForkJoinPool-pooliin.
  • Huonosti jaettavat lähteet, pieni datamäärä ja kallis yhdistäminen heikentävät kaikki rinnakkaisuuden hyötyä.
Aloita maksutta

Opi Java tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
104
Oppitunnit
374

Usein kysytyt kysymykset

Onko oppitunti ”Yleiset sudenkuopat” ilmainen?

Kyllä – oppitunnin ”Yleiset sudenkuopat” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Yleiset sudenkuopat”?

Järjestys, boxing ja yhteinen säieallas. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Yleiset sudenkuopat”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?

Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Rinnakkaisvirtojen luonti
  2. Milloin rinnakkaisuus auttaa
  3. Säieturvallisuus ja sivuvaikutukset
  4. Yleiset sudenkuopat
← Takaisin: Java Academy