OpenJDK Project Loom

1. Oversigt

I denne artikel ser vi hurtigt på Project Loom. I det væsentlige det primære mål med Project Loom er at understøtte en høj-gennemstrømning, letvægts samtidig model i Java.

2. Project Loom

Project Loom er et forsøg fra OpenJDK-samfundet om at introducere en letvægtskonkurrencekonstruktion til Java. Prototyperne til Loom hidtil har introduceret en ændring i JVM såvel som Java-biblioteket.

Selvom der ikke er nogen planlagt frigivelse til Loom endnu, kan vi få adgang til de nylige prototyper på Project Looms wiki.

Før vi diskuterer de forskellige begreber i Loom, lad os diskutere den aktuelle samtidighedsmodel i Java.

3. Java's samtidighedsmodel

I øjeblikket, Tråd repræsenterer kerneabstraktionen af ​​samtidighed i Java. Denne abstraktion sammen med andre samtidige API'er gør det let at skrive samtidige applikationer.

Da Java bruger OS-kernetråde til implementeringen, opfylder den imidlertid ikke dagens krav om samtidighed. Der er især to store problemer:

  1. Tråde kan ikke matche skalaen for domænes enhed af samtidighed. For eksempel tillader applikationer normalt op til millioner af transaktioner, brugere eller sessioner. Antallet af tråde, der understøttes af kernen, er dog meget mindre. Således er en Thread for hver bruger, transaktion eller session er ofte ikke mulig.
  2. De fleste samtidige applikationer har brug for en vis synkronisering mellem tråde til hver anmodning. På grund af dette, en dyr kontekstskift sker mellem OS-tråde.

En mulig løsning på sådanne problemer er brugen af ​​asynkrone samtidige API'er. Almindelige eksempler er Fuldført og RxJava. Forudsat at sådanne API'er ikke blokerer kernetråden, giver det en applikation en finere kornet samtidighedskonstruktion oven på Java-tråde.

På den anden side, sådanne API'er er sværere at debugge og integrere med ældre API'er. Og således er der et behov for en letvægtskonkurrencekonstruktion, der er uafhængig af kernetråde.

4. Opgaver og planlæggere

Enhver implementering af en tråd, enten let eller tung, afhænger af to konstruktioner:

  1. Opgave (også kendt som en fortsættelse) - En sekvens af instruktioner, der kan suspendere sig selv for en blokering
  2. Scheduler - Til tildeling af fortsættelsen til CPU'en og tildeling af CPU'en fra en fortsat pause

I øjeblikket, Java er afhængig af OS-implementeringer til både fortsættelsen og planlæggeren.

For at kunne suspendere en fortsættelse er det nu nødvendigt at gemme hele call-stacken. Og på samme måde skal du hente opkaldsstakken ved genoptagelse. Da OS-implementeringen af ​​fortsættelser inkluderer den oprindelige opkaldsstak sammen med Java's opkaldsstak, resulterer det i et stort fodaftryk.

Et større problem er dog brugen af ​​OS-planlægning. Da planlæggeren kører i kernetilstand, er der ingen forskel mellem tråde. Og det behandler hver CPU-anmodning på samme måde.

Denne type planlægning er især ikke Java-applikationer.

Overvej f.eks. En applikationstråd, der udfører nogle handlinger på anmodningerne og derefter videregiver dataene til en anden tråd til videre behandling. Her, det ville være bedre at planlægge begge disse tråde på den samme CPU. Men da planlæggeren er agnostisk for den tråd, der anmoder om CPU, er dette umuligt at garantere.

Project Loom foreslår at løse dette igennem brugertilstandstråde, der er afhængige af Java-runtime-implementering af fortsættelser og planlæggere i stedet for OS-implementering.

5. Fibre

I de nylige prototyper i OpenJDK hedder en ny klasse Fiber introduceres til biblioteket sammen med Tråd klasse.

Siden det planlagte bibliotek for Fibre ligner Tråd, bør brugerimplementeringen også forblive ens. Der er dog to hovedforskelle:

  1. Fiber ville pakke enhver opgave i en intern fortsættelse af brugertilstand. Dette gør det muligt for opgaven at suspendere og genoptage i Java-runtime i stedet for kernen
  2. En tilslutbar bruger-mode planlægger (ForkJoinPool, f.eks.) ville blive brugt

Lad os gennemgå disse to emner i detaljer.

6. Fortsættelser

En fortsættelse (eller co-rutine) er en sekvens af instruktioner, der kan give og genoptages af den, der ringer op på et senere tidspunkt.

Hver fortsættelse har et indgangspunkt og et udbyttepunkt. Udbyttepunktet er, hvor det blev suspenderet. Hver gang opkalderen genoptager fortsættelsen, vender kontrollen tilbage til det sidste udbyttepunkt.

Det er vigtigt at forstå at denne suspendering / genoptagelse nu forekommer i sprogkørselstiden i stedet for OS. Derfor forhindrer det den dyre kontekstskift mellem kernetråde.

I lighed med tråde har Project Loom til formål at understøtte indlejrede fibre. Da fibre er afhængige af fortsættelser internt, skal det også understøtte indlejrede fortsættelser. For at forstå dette bedre, overvej en klasse Fortsættelse der tillader indlejring:

Fortsættelse kont1 = ny Fortsættelse (() -> {Fortsættelse forts2 = ny Fortsættelse (() -> {// gør noget suspendere (SCOPE_CONT_2); suspendere (SCOPE_CONT_1);});});

Som vist ovenfor kan den indlejrede fortsættelse suspendere sig selv eller en hvilken som helst af de indesluttende fortsættelser ved at passere en omfangsvariabel. Af denne grund, de er kendt som afgrænset fortsættelser.

Da suspendering af en fortsættelse også vil kræve, at den gemmer opkaldsstakken, er det også et mål for projektet Loom at tilføje letvægtsgenvinding, mens genoptagelsen fortsættes.

7. Planlægning

Tidligere diskuterede vi manglerne ved OS-planlæggeren ved planlægning af relaterede tråde på den samme CPU.

Selvom det er et mål for Project Loom at tillade pluggbare planlæggere med fibre, ForkJoinPool i asynkron tilstand vil blive brugt som standardplanlægning.

ForkJoinPool arbejder på arbejde-stjæle algoritme. Således opretholder hver tråd en opgave-deque og udfører opgaven fra hovedet. Desuden blokerer enhver inaktiv tråd ikke, venter på opgaven og trækker den fra halen af ​​en anden tråds deque i stedet.

Den eneste forskel i asynkron tilstand er, at arbejdertrådene stjæler opgaven fra hovedet på en anden deque.

ForkJoinPool tilføjer en opgave, der er planlagt af en anden kørende opgave til den lokale kø. Derfor udføres det på den samme CPU.

8. Konklusion

I denne artikel diskuterede vi problemerne i Java's nuværende samtidighedsmodel og de ændringer, der er foreslået af Project Loom.

Dermed definerede vi også opgaver og planlæggere og så på, hvordan Fibre og ForkJoinPool kunne give et alternativ til Java ved hjælp af kernetråde.


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