OpenJDK Project Loom

1. Oversikt

I denne artikkelen tar vi en rask titt på Project Loom. I hovedsak, det primære målet for Project Loom er å støtte en høy gjennomstrømning, lett samtidig modell i Java.

2. Project Loom

Project Loom er et forsøk fra OpenJDK-fellesskapet å introdusere en lett samtidighetskonstruksjon til Java. Prototypene for Loom så langt har introdusert en endring i JVM så vel som Java-biblioteket.

Selv om det ikke er noen planlagt utgivelse for Loom ennå, kan vi få tilgang til de siste prototypene på Project Looms wiki.

Før vi diskuterer de forskjellige begrepene i Loom, la oss diskutere den nåværende samtidighetsmodellen i Java.

3. Java's samtidighetsmodell

For øyeblikket Tråd representerer kjerneabstraksjonen av samtidighet i Java. Denne abstraksjonen, sammen med andre samtidige API-er, gjør det enkelt å skrive samtidige applikasjoner.

Men siden Java bruker OS-kjernetråder for implementeringen, oppfyller den ikke dagens krav om samtidighet. Det er spesielt to store problemer:

  1. Tråder kan ikke matche skalaen til domenets enhet av samtidighet. For eksempel tillater applikasjoner vanligvis opptil millioner transaksjoner, brukere eller økter. Antall tråder som støttes av kjernen er imidlertid mye mindre. Dermed a Thread for hver bruker, transaksjon eller økt er ofte ikke mulig.
  2. De fleste samtidige applikasjoner trenger litt synkronisering mellom tråder for hver forespørsel. På grunn av dette, en dyr kontekstsvitsj skjer mellom OS-tråder.

En mulig løsning på slike problemer er bruk av asynkrone samtidige API-er. Vanlige eksempler er Fullførbar fremtid og RxJava. Forutsatt at slike API-er ikke blokkerer kjernetråden, gir det et program en finere kornet samtidighetskonstruksjon på toppen av Java-tråder.

På den andre siden, slike API-er er vanskeligere å feilsøke og integrere med eldre API-er. Og dermed er det behov for en lett samtidigkonstruksjon som er uavhengig av kjernetråder.

4. Oppgaver og planleggere

Enhver implementering av en tråd, enten lett eller tung, avhenger av to konstruksjoner:

  1. Oppgave (også kjent som en fortsettelse) - En sekvens av instruksjoner som kan suspendere seg selv for noen blokkeringsoperasjoner
  2. Planlegger - For å tilordne fortsettelsen til CPUen og tildele CPUen fra en videreført pause

For øyeblikket Java er avhengig av OS-implementeringer for både fortsettelsen og planleggeren.

Nå, for å avbryte en fortsettelse, er det nødvendig å lagre hele samtalestakken. Og på samme måte kan du hente samtalestakken ved gjenopptakelse. Siden OS-implementeringen av fortsettelser inkluderer den opprinnelige samtalestakken sammen med Java sin samtalestabel, resulterer det i et stort fotavtrykk.

Et større problem er imidlertid bruken av OS-planlegger. Siden planleggeren kjører i kjernemodus, er det ingen forskjell mellom tråder. Og den behandler hver CPU-forespørsel på samme måte.

Denne typen planlegging er spesielt ikke Java-applikasjoner.

Tenk for eksempel på en søknadstråd som utfører noen handlinger på forespørslene og deretter overfører dataene til en annen tråd for videre behandling. Her, det ville være bedre å planlegge begge disse trådene på samme CPU. Men siden planleggeren er agnostisk for tråden som ber om CPU, er dette umulig å garantere.

Project Loom foreslår å løse dette gjennom brukermodetråder som er avhengige av implementering av Java runtime av fortsettelser og planleggere i stedet for OS-implementering.

5. Fibre

I de nylige prototypene i OpenJDK, en ny klasse som heter Fiber introduseres til biblioteket sammen med Tråd klasse.

Siden det planlagte biblioteket for Fibre den er lik Tråd, bør brukerimplementeringen også være lik. Imidlertid er det to hovedforskjeller:

  1. Fiber ville pakke en hvilken som helst oppgave i en intern fortsettelse av brukermodus. Dette vil tillate oppgaven å suspendere og gjenoppta i Java-kjøretid i stedet for kjernen
  2. En pluggbar brukermodusplanlegger (ForkJoinPool, for eksempel) ville bli brukt

La oss gå gjennom disse to elementene i detalj.

6. Fortsettelser

En fortsettelse (eller co-rutine) er en sekvens av instruksjoner som kan gi og gjenopptas av den som ringer på et senere tidspunkt.

Hver fortsettelse har et inngangspunkt og et avkastningspunkt. Avkastningspunktet er der det ble suspendert. Hver gang innringeren fortsetter fortsettelsen, går kontrollen tilbake til det siste avkastningspunktet.

Det er viktig å innse at denne suspendering / gjenoppta nå forekommer i språketid i stedet for operativsystemet. Derfor forhindrer det den dyre kontekstvekslingen mellom kjernetråder.

I likhet med tråder tar Project Loom sikte på å støtte nestede fibre. Siden fibre er avhengige av fortsettelser internt, må det også støtte nestede fortsettelser. For å forstå dette bedre, bør du vurdere en klasse Fortsettelse som gjør det mulig å hekke:

Fortsettelse forts1 = ny Fortsettelse (() -> {Fortsettelse forts2 = ny Fortsettelse (() -> {// gjør noe suspendere (SCOPE_CONT_2); suspendere (SCOPE_CONT_1);});});

Som vist ovenfor kan den nestede fortsettelsen suspendere seg selv eller hvilken som helst av de vedlagte fortsettelsene ved å sende en omfangsvariabel. Av denne grunn, de er kjent som scoped fortsettelser.

Siden suspensjon av en fortsettelse også vil kreve at den lagrer samtalestakken, er det også et mål for prosjektet Loom å legge til lett henting av stakk mens du fortsetter fortsettelsen.

7. Planlegger

Tidligere diskuterte vi manglene til OS-planleggeren ved å planlegge relaterte tråder på samme CPU.

Selv om det er et mål for Project Loom å tillate pluggbare planleggere med fibre, ForkJoinPool i asynkron modus vil bli brukt som standard planlegger.

ForkJoinPool fungerer på arbeids stjele algoritme. Dermed opprettholder hver tråd en oppgave deque og utfører oppgaven fra hodet. Videre blokkerer ikke tomgangstråd, venter på oppgaven og trekker den fra halen til en annen tråds deque i stedet.

Den eneste forskjellen i asynkron modus er at arbeidertrådene stjeler oppgaven fra hodet til en annen deque.

ForkJoinPool legger til en oppgave som er planlagt av en annen oppgave i den lokale køen. Derfor utfører du den på samme CPU.

8. Konklusjon

I denne artikkelen diskuterte vi problemene i Java nåværende samtidighetsmodell og endringene som ble foreslått av Project Loom.

Ved å gjøre dette definerte vi også oppgaver og planleggere og så på hvordan Fibre og ForkJoinPool kan gi et alternativ til Java ved hjelp av kjernetråder.


$config[zx-auto] not found$config[zx-overlay] not found