Razvoj projekta OpenJDK

1. Pregled

U ovom ćemo članku na brzinu pogledati Project Loom. U suštini, primarni cilj Project Loom-a je podržati visokopropusni, lagani model istodobnosti u Javi.

2. Projektni razboj

Project Loom je pokušaj zajednice OpenJDK da na Javu uvede lagani konstrukt istodobnosti. Dosadašnji prototipovi Loom-a uveli su promjenu u JVM-u, kao i u Java knjižnici.

Iako još nema predviđenog izdanja za Loom, najnovijim prototipovima možemo pristupiti na wikiju Project Loom.

Prije nego što razgovaramo o raznim konceptima Looma, razgovarajmo o trenutnom modelu istodobnosti u Javi.

3. Javin model istodobnosti

Sada, Nit predstavlja jezgru apstrakcije istodobnosti u Javi. Ova apstrakcija, zajedno s ostalim istodobnim API-ima, olakšava pisanje istodobnih aplikacija.

Međutim, budući da Java koristi OS jezgrene niti za implementaciju, ona ne ispunjava današnji zahtjev za paralelnošću. Dva su glavna problema posebno:

  1. Niti ne može odgovarati ljestvici jedinice istovremenosti domene. Na primjer, aplikacije obično omogućuju do milijune transakcija, korisnika ili sesija. Međutim, broj niti koje jezgra podržava je mnogo manji. Dakle, a Thread za svakog korisnika, transakcija ili sesija često nije izvediva.
  2. Većina istodobnih aplikacija zahtijeva određenu sinkronizaciju između niti za svaki zahtjev. Zbog ovoga, događa se skupo prebacivanje konteksta između niti OS-a.

Moguće rješenje takvih problema je upotreba asinkronih istodobnih API-ja. Uobičajeni primjeri su CompletableFuture i RxJava. Pod uvjetom da takvi API-ji ne blokiraju nit jezgre, aplikaciji daje finozrnati konstrukt istodobnosti na vrhu Java niti.

S druge strane, takve je API-je teže ispraviti i integrirati s naslijeđenim API-ima. Dakle, postoji potreba za laganim istodobnim konstruktom koji je neovisan o nitima jezgre.

4. Zadaci i planeri

Bilo koja primjena niti, lagana ili teška, ovisi o dvije konstrukcije:

  1. Zadatak (poznat i kao nastavak) - niz uputa koji se može obustaviti zbog neke blokade
  2. Planer - Za dodjeljivanje nastavka CPU-u i ponovnu dodjelu CPU-a iz pauziranog nastavka

Sada, Java se oslanja na implementacije OS-a i za nastavak i za planer.

Sada, da bi se obustavio nastavak, potrebno je pohraniti čitav niz poziva. I slično, dohvatite skup poziva nakon nastavka. Budući da implementacija OS-a u nastavke uključuje izvorni skup poziva zajedno s Java-ovim skupom poziva, to rezultira velikim tragom.

Međutim, veći je problem uporaba OS planera. Budući da se planer izvodi u načinu jezgre, nema razlike između niti. I svaki CPU zahtjev tretira na isti način.

Ova vrsta zakazivanja je nije optimalno za Java programe posebno.

Na primjer, razmotrite nit aplikacije koja izvodi neku radnju na zahtjevima, a zatim podatke prosljeđuje u drugu nit za daljnju obradu. Ovdje, bilo bi bolje rasporediti obje ove niti na istom CPU-u. No budući da je planer agnostičan za nit koja zahtijeva CPU, to je nemoguće jamčiti.

Project Loom predlaže da se to riješi do kraja nitima u korisničkom načinu rada koje se oslanjaju na Java izvedbenu implementaciju nastavka i planere umjesto na implementaciju OS-a.

5. Vlakna

U nedavnim prototipovima u OpenJDK, nova je klasa nazvana Vlakno uvodi se u knjižnicu uz Nit razred.

Budući da je planirana knjižnica za Vlakna je sličan Nit, korisnička implementacija također bi trebala ostati slična. Međutim, postoje dvije glavne razlike:

  1. Vlakno bi zamotajte bilo koji zadatak u interni nastavak korisničkog načina. To bi omogućilo zadatku da suspendira i nastavi u Java izvođenju umjesto u jezgri
  2. Priključni planer korisničkog načina (ForkJoinPool, na primjer) koristila bi se

Prođimo detaljno kroz ove dvije stavke.

6. Nastavci

Nastavak (ili ko-rutina) je niz uputa koje pozivatelj može dati i nastaviti u kasnijoj fazi.

Svaki nastavak ima ulaznu i prinosnu točku. Točka prinosa je mjesto na kojem je suspendirana. Kad god pozivatelj nastavi nastavak, kontrola se vraća na posljednju granicu prinosa.

Važno je shvatiti da se ova obustava / nastavak sada pojavljuje u izvršavanju jezika umjesto u OS-u. Stoga sprječava skupo prebacivanje konteksta između niti jezgre.

Slično nitima, Project Loom želi podržati ugniježđena vlakna. Budući da se vlakna interno oslanjaju na nastavke, ona također moraju podržavati ugniježđena nastavka. Da biste ovo bolje razumjeli, razmislite o predavanju Nastavak koji omogućuje gniježđenje:

Nastavak cont1 = novi Nastavak (() -> {Nastavak cont2 = novi Nastavak (() -> {// učinite nešto obustaviti (SCOPE_CONT_2); obustaviti (SCOPE_CONT_1);});});

Kao što je gore prikazano, ugniježđeni nastavak može suspendirati sebe ili bilo koji od nastavka koji slijede dodavanjem varijable opsega. Zbog ovog razloga, poznati su kao opseg nastavci.

Budući da bi obustavljanje nastavka također zahtijevalo spremanje niza poziva, cilj projekta Loom je i dodavanje lakog pronalaženja steka tijekom nastavka nastavka.

7. Planer

Ranije smo razgovarali o nedostacima OS planera u zakazivanju relativnih niti na istom CPU-u.

Iako je cilj Project Loom-a omogućiti priključive planere s vlaknima, ForkJoinPool u asinkronom načinu rada koristit će se kao zadani planer.

ForkJoinPool radi na algoritam krađe rada. Dakle, svaka nit održava zadatke zadatka i izvršava zadatak iz glave. Nadalje, nijedna neaktivna nit ne blokira, čeka zadatak i umjesto toga ga izvlači iz repa deke druge niti.

Jedina razlika u asinkronom načinu rada je ta radničke niti kradu zadatak s glave drugog deque-a.

ForkJoinPool dodaje zadatak koji je rasporedio drugi izvršeni zadatak u lokalni red. Dakle, izvršavanje na istom CPU.

8. Zaključak

U ovom smo članku razgovarali o problemima u trenutnom Java-ovom modelu istodobnosti i promjenama koje je predložio Project Loom.

Pritom smo također definirali zadatke i planere te pogledali kako Vlakna i ForkJoinPool mogu pružiti alternativu Javi pomoću niti jezgre.