Alusta- ja virtuaalisäikeet
Milloin kumpaakin kannattaa käyttää.
Alusta- ja virtuaalisäikeet on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/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.
Kaksi säietyyppiä
Javassa on nyt kaksi säietyyppiä. Alustasäikeet ovat perinteisiä käyttöjärjestelmäsäikeiden kääreitä. Virtuaalisäikeet ovat kevyitä ja JVM:n hallinnoimia.
Sen tietäminen, milloin kumpaakin kannattaa käyttää, on skaalautuvan samanaikaisen Java-koodin ydin.
Alustasäikeen luominen
Alustasäie luodaan kutsulla Thread.ofPlatform(), joka on Thread.ofVirtual()-metodin vastine.
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread p = Thread.ofPlatform().name("native-worker").start(() ->
System.out.println("Platform? " + !Thread.currentThread().isVirtual()));
p.join();
}
}Kustannusten vertailu
Alustasäikeet ovat raskaita:
- Niille varataan noin 1 Mt pinoa kutakin säiettä kohden
- Niiden luominen on hidasta
- Niitä voidaan luoda vain muutamia tuhansia
Virtuaalisäikeet ovat edullisia: niiden aloituspino on pieni, ne luodaan nopeasti ja niitä voidaan luoda miljoonia.
I/O-sidonnainen työ
Jos tehtävä käyttää suurimman osan ajastaan verkon, levyn tai tietokannan odottamiseen, virtuaalisäikeet ovat selvästi parempi vaihtoehto.
Kun yksi virtuaalisäie estyy, sen kantajasäie vapautuu muiden suorittamiseen, joten muutama käyttöjärjestelmäsäie voi palvella tuhansia pyyntöjä.
CPU-sidonnainen työ
Puhtaassa laskennassa, joka ei koskaan esty, virtuaalisäikeet eivät nopeuta suoritusta. Suorituskykyä rajoittaa ytimien määrä.
Tässä tilanteessa prosessorien määrän mukaan mitoitettu kiinteä pooli on oikea työkalu.
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws Exception {
int cores = Runtime.getRuntime().availableProcessors();
try (ExecutorService cpu = Executors.newFixedThreadPool(cores)) {
Future<Long> f = cpu.submit(() -> {
long s = 0;
for (long i = 0; i < 1_000_000L; i++) s += i;
return s;
});
System.out.println("Cores: " + cores + ", sum: " + f.get());
}
}
}Estymisen simulointi
Tämä koodikatkelma näyttää useiden virtuaalisäikeiden nukkuvan samanaikaisesti. Nukkuminen toimii tässä estyvän I/O:n vastineena. Kuvitelkaa, että 10 000 alustasäiettä tekisi saman.
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) {
AtomicInteger done = new AtomicInteger();
try (ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10_000; i++) {
exec.submit(() -> {
try { Thread.sleep(50); } catch (InterruptedException e) {}
done.incrementAndGet();
});
}
}
System.out.println("Finished blocking tasks: " + done.get());
}
}Daemon-tila
Virtuaalisäikeet ovat aina daemon-säikeitä, eikä niitä voi muuttaa muiksi kuin daemon-säikeiksi. Alustasäikeet perivät oletusarvoisesti luojansa daemon-tilan, mutta niiden tila voidaan määrittää erikseen.
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread v = Thread.ofVirtual().unstarted(() -> {});
Thread p = Thread.ofPlatform().unstarted(() -> {});
System.out.println("virtual daemon: " + v.isDaemon());
System.out.println("platform daemon: " + p.isDaemon());
}
}Prioriteetit ohitetaan
Virtuaalisäikeet ilmoittavat aina prioriteetikseen NORM_PRIORITY, eikä prioriteetin asettamisella ole vaikutusta. Ajoituksesta huolehtii JVM, ei käyttöjärjestelmän ajoitin.
public class Main {
public static void main(String[] args) {
Thread v = Thread.ofVirtual().unstarted(() -> {});
v.setPriority(Thread.MAX_PRIORITY);
System.out.println("Priority is still: " + v.getPriority());
}
}Valintaohje
Käytännön nyrkkisääntö:
- Paljon I/O:n odottamiseen jääviä tehtäviä? Käyttäkää virtuaalisäikeitä.
- Suorittimen rajoittamaa raskasta laskentaa? Käyttäkää kiinteää alustasäikeiden poolia.
- Tarvitsetteko käyttöjärjestelmätason säikeiden hienosäätöä, kuten prioriteetin tai affiniteetin määrittämistä? Käyttäkää alustasäikeitä.
Ne toimivat rinnakkain
Teidän ei tarvitse valita yhtä vaihtoehtoa koko ohjelmaa varten. Tyypillisessä sovelluksessa virtuaalisäikeitä käytetään pyyntöjen käsittelyyn ja pientä alustasäikeiden poolia suoritinta kuormittaviin osioihin.
Molemmissa käytetään samaa Thread-rajapintaa, joten niiden yhdistäminen on saumatonta.
Vinkki siirtymiseen
Kun siirrätte I/O-raskasta palvelua virtuaalisäikeisiin, pienin muutos on executorin vaihtaminen: korvatkaa kiinteä tai välimuistia käyttävä pooli kutsulla newVirtualThreadPerTaskExecutor().
Varokaa kuitenkin pinningiä ja ThreadLocalien väärinkäyttöä, joita käsitellään seuraavalla oppitunnilla.
Pikatarkistus
Valitkaa kuormitus, jossa virtuaalisäikeistä on selvimmin hyötyä.
Kertaus
Vertailitte kahta säiemallia:
- Alustasäikeet: raskaita ja käyttöjärjestelmän tukemia, sopivat parhaiten CPU-sidonnaiseen työhön ja käyttöjärjestelmätason säätöön
- Virtuaalisäikeet: edullisia ja JVM:n hallinnoimia, aina daemon-säikeitä, sopivat parhaiten I/O-sidonnaiseen samanaikaisuuteen
- Ne toimivat rinnakkain ja käyttävät samaa APIa
Seuraavaksi käsitellään pinningiä ja ThreadLocaleja.
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 ”Alusta- ja virtuaalisäikeet” ilmainen?
Kyllä – oppitunnin ”Alusta- ja virtuaalisäikeet” 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 ”Alusta- ja virtuaalisäikeet”?
Milloin kumpaakin kannattaa käyttää. 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 3/4.
Kuinka kauan ”Alusta- ja virtuaalisäikeet”-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
- Mitä virtuaalisäikeet ovat
- Virtuaalisäikeiden luonti
- Alusta- ja virtuaalisäikeet
- Sudenkuopat: pinning ja ThreadLocalit