window.pipedriveLeadboosterConfig = { base: leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster on juba olemas') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Samaaegsus Java's 1. osa - Sissejuhatus - The Codest
The Codest
  • Meie kohta
  • Teenused
    • Tarkvaraarendus
      • Frontend arendus
      • Backend arendus
    • Staff Augmentation
      • Frontend arendajad
      • Backend arendajad
      • Andmeinsenerid
      • Pilveinsenerid
      • QA insenerid
      • Muud
    • See nõuandev
      • Audit ja nõustamine
  • Tööstusharud
    • Fintech & pangandus
    • E-commerce
    • Adtech
    • Healthtech
    • Tootmine
    • Logistika
    • Autotööstus
    • IOT
  • Väärtus
    • CEO
    • CTO
    • Tarnejuht
  • Meie meeskond
  • Case Studies
  • Tea kuidas
    • Blogi
    • Kohtumised
    • Veebiseminarid
    • Ressursid
Karjäärivõimalused Võtke ühendust
  • Meie kohta
  • Teenused
    • Tarkvaraarendus
      • Frontend arendus
      • Backend arendus
    • Staff Augmentation
      • Frontend arendajad
      • Backend arendajad
      • Andmeinsenerid
      • Pilveinsenerid
      • QA insenerid
      • Muud
    • See nõuandev
      • Audit ja nõustamine
  • Väärtus
    • CEO
    • CTO
    • Tarnejuht
  • Meie meeskond
  • Case Studies
  • Tea kuidas
    • Blogi
    • Kohtumised
    • Veebiseminarid
    • Ressursid
Karjäärivõimalused Võtke ühendust
Tagasi nool TAGASI
2022-06-15
Tarkvaraarendus

Samaaegsus Java's 1. osa - Sissejuhatus

The Codest

Rafal Sawicki

Java arendaja

Loe meie blogisarja esimest osa, mis on pühendatud Java paralleelsusele. Järgnevas artiklis vaatleme lähemalt niidi ja protsessi erinevusi, niidipooli, täitjaid ja palju muud!

Üldiselt on tavapärane programmeerimismeetod järjestikune. Kõik programmis toimub üks samm korraga.
Kuid tegelikult on paralleel see, kuidas kogu maailm töötab - see on võime täita rohkem kui ühte ülesannet samaaegselt.

Niit vs. protsess

Arutleda selliste edasijõudnud teemade üle nagu paralleelsus Java või multithreading, peame leppima kokku mõnes ühises definitsioonis, et olla kindel, et oleme ühel ja samal leheküljel.

Alustame põhitõdedest. Mittesekventsionaalses maailmas on meil kahte liiki samaaegsuse esindajad: protsessid ja
niidid. Protsess on käimasoleva programmi instants. Tavaliselt on see teistest protsessidest isoleeritud.
Operatsioonisüsteem vastutab igale protsessile ressursside määramise eest. Lisaks sellele toimib see dirigendina, mis
ajakava ja kontrollib neid.

Niit on omamoodi protsess, kuid madalamal tasemel, seetõttu nimetatakse seda ka kergeks niidiks. Mitu niiti võib töötada ühes
protsess. Siinkohal tegutseb programm niitide ajaplaneerijana ja kontrollerina. Sel viisil näivad üksikud programmid teha
mitu ülesannet korraga.

Põhiline erinevus niitide ja protsesside vahel on isolatsioonitase. Protsessil on oma komplekt
ressursse, samas kui lõim jagab andmeid teiste lõimedega. See võib tunduda vigaohtlik lähenemine ja seda see ka on. Sest
nüüd ei keskendu me sellele, sest see ei kuulu käesoleva artikli reguleerimisalasse.

Protsessid, niidid - ok... Aga mis täpselt on samaaegsus? Samaaegsus tähendab, et saab täita mitu ülesannet korraga.
aeg. See ei tähenda, et need ülesanded peavad toimuma samaaegselt - see ongi paralleelsus. Concurrenc in Javay samuti ei ole
nõuavad, et teil oleks mitu protsessorit või isegi mitu südamikku. Seda on võimalik saavutada ühe tuumaga keskkonnas, kasutades ära
konteksti vahetamine.

Samaaegsusega seotud termin on mitmelaiendamine. See on programmide omadus, mis võimaldab neil täita korraga mitut ülesannet. Mitte iga programm ei kasuta seda lähenemist, kuid neid, mis seda teevad, võib nimetada multithreaded'iks.

Me oleme peaaegu valmis, vaid veel üks määratlus. Asünkroonsus tähendab, et programm sooritab mitteblokeerivaid operatsioone.
See algatab ülesande ja jätkab seejärel vastuse ootamise ajal muude asjadega. Kui ta saab vastuse, saab ta sellele reageerida.

Kõik see jazz

Vaikimisi on iga Java rakendus töötab ühes protsessis. Selles protsessis on üks niit, mis on seotud main() meetod
taotlus. Kuid, nagu mainitud, on võimalik kasutada mitme niidi mehhanisme ühes
programm.

Käivitatav

Teema on Java klass, kus toimub maagia. See on eelpool mainitud niidi objekti representatsioon. Et
luua oma lõim, saate laiendada Teema klass. See ei ole siiski soovitatav lähenemisviis. Niidid tuleks kasutada mehhanismi, mis täidab ülesannet. Ülesanded on tükid kood mida me tahame käivitada samaaegses režiimis. Me võime neid defineerida, kasutades Käivitatav liides.

Kuid teooriast piisab, paneme oma koodi sinna, kus meie suu on.

Probleem

Oletame, et meil on paar numbrite massiivi. Iga massiivi puhul tahame teada massiivi numbrite summat. Olgu
teeselda, et selliseid massiive on palju ja igaüks neist on suhteliselt suur. Sellistes tingimustes tahame kasutada samaaegsust ja summeerida iga massiivi eraldi ülesandena.

int[] a1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] a2 = {10, 10, 10, 10, 10, 10, 10, 10, 10, 10};
int[] a3 = {3, 4, 3, 3, 4, 3, 4, 2, 1, 3, 7};

Runnable task1 = () -> { {
    int sum = Arrays.stream(a1).sum();
    System.out.println("1. Summa on: " + sum);
};

Runnable task2 = () -> { {
    int sum = Arrays.stream(a2).sum();
    System.out.println("2. Summa on: " + sum);
};

Runnable task3 = () -> { {
    int sum = Arrays.stream(a3).sum();
    System.out.println("3. Summa on: " + sum);
};

new Thread(task1).start();
new Thread(task2).start();
new Thread(task3).start();

Nagu ülaltoodud koodist näha Käivitatav on funktsionaalne liides. See sisaldab ühte abstraktset meetodit run()
ilma argumentideta. Veebileht Käivitatav liidest peaks rakendama iga klass, mille instantsid on mõeldud kasutamiseks
mida teostab niit.

Kui olete määratlenud ülesande, saate selle käivitamiseks luua lõime. Seda saab teha järgmiselt new Thread() konstruktor, mis
võtab Käivitatav selle argumendiks.

Viimane samm on start() äsja loodud teema. APIs on ka run() meetodid Käivitatav ja aastal
Teema. See ei ole aga viis, kuidas kasutada Java's samaaegsust. Otsekõne igale neist meetoditest annab tulemuseks
ülesande täitmine samas niidis, mis main() meetod töötab.

Niidipargid ja täitjad

Kui ülesandeid on palju, ei ole iga ülesande jaoks eraldi niidi loomine hea mõte. Luua Teema on
raske operatsioon ja palju parem on olemasolevaid niite taaskasutada kui uusi luua.

Kui programm loob palju lühiajalisi niite, on parem kasutada niidipooli. Niidipool sisaldab mitmeid
käivitamisvalmis, kuid hetkel mitteaktiivsed niidid. Andmine Käivitatav basseini põhjustab ühe niidi üleskutse
run() meetod antud Käivitatav. Pärast ülesande täitmist on niit endiselt olemas ja on tühikäigul.

Okei, sa saad aru - eelista niidipooli käsitsi loomise asemel. Aga kuidas saab kasutada niidipooli? Veebileht Täitjad
klassil on mitmeid staatilisi tehasesiseseid meetodeid niidipoolide konstrueerimiseks. Näiteks newCachedThredPool() loob
bassein, kuhu luuakse vajaduse korral uusi niite ja tühjaksjäänud niite hoitakse 60 sekundit. Seevastu,
newFixedThreadPool() sisaldab fikseeritud niitide kogumit, kus tühjad niidid hoitakse lõputult.

Vaatame, kuidas see meie näites toimida võiks. Nüüd ei pea me niite käsitsi looma. Selle asemel peame looma
ExecutorService mis pakub niitide kogumit. Seejärel saame sellele ülesandeid määrata. Viimane samm on niidi sulgemine
basseini, et vältida mälulekkeid. Ülejäänud eelmine kood jääb samaks.

ExecutorService executor = Executors.newCachedThreadPool();

executor.submit(task1);
executor.submit(task2);
executor.submit(task3);

executor.shutdown();

Väljakutsetav

Käivitatav näib olevat nutikas viis samaaegsete ülesannete loomiseks, kuid sellel on üks suur puudus. See ei saa tagastada ühtegi
väärtus. Veelgi enam, me ei saa kindlaks teha, kas ülesanne on lõpetatud või mitte. Samuti ei tea me, kas see on lõpetatud.
tavaliselt või erandkorras. Nende hädade lahendus on Väljakutsetav.

Väljakutsetav on sarnane Käivitatav viisil ka asünkroonseid ülesandeid. Peamine erinevus seisneb selles, et see suudab
tagastada väärtus. Tagastusväärtus võib olla mis tahes (mitte-primitiivse) tüübiga, sest Väljakutsetav liides on parameetriga tüüp.
Väljakutsetav on funktsionaalne liides, millel on call() meetod, mis võib visata Erand.

Nüüd vaatame, kuidas me saame võimendada Väljakutsetav meie massiivi probleem.

int[] a1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] a2 = {10, 10, 10, 10, 10, 10, 10, 10, 10, 10};
int[] a3 = {3, 4, 3, 3, 4, 3, 4, 2, 1, 3, 7};

Callable task1 = () -> Arrays.stream(a1).sum();
Callable task2 = () -> Arrays.stream(a2).sum();
Callable task3 = () -> Arrays.stream(a3).sum();

ExecutorService executor = Executors.newCachedThreadPool();
Future future1 = executor.submit(task1);
Future future2 = executor.submit(task2);
Future future3 = executor.submit(task3);

System.out.println("1. Summa on: " + future1.get());
System.out.println("2. Summa on: " + future2.get());
System.out.println("3. Summa on: " + future3.get());

executor.shutdown();

Okei, me näeme, kuidas Väljakutsetav luuakse ja seejärel esitatakse ExecutorService. Aga mis kurat on Tulevik?
Tulevik toimib sildana lõimede vahel. Iga massiivi summa toodetakse eraldi niidiga ja meil on vaja viisi, kuidas teha
saada need tulemused tagasi main().

Tulemuse kättesaamiseks aadressilt Tulevik me peame helistama get() meetod. Siin võib juhtuda üks kahest asjast. Esiteks võib
arvutuste tulemus, mille on teinud Väljakutsetav on saadaval. Siis me saame selle kohe. Teiseks, tulemus ei ole
veel valmis. Sel juhul get() meetod blokeerib, kuni tulemus on saadaval.

ComputableFuture

Küsimus seoses Tulevik on see, et see töötab "push-paradigmas". Kasutades Tulevik sa pead olema nagu ülemus, kes
küsib pidevalt: "Kas teie ülesanne on täidetud? Kas see on valmis?", kuni see annab tulemuse. Pideva surve all tegutsemine on
kallis. Palju parem oleks tellida Tulevik mida teha, kui ta on oma ülesandega valmis. Kahjuks,
Tulevik ei saa seda teha, kuid ComputableFuture saab.

ComputableFuture töötab "tõmbeparadigmas". Me saame öelda, mida teha tulemusega, kui see on oma ülesanded täitnud. See
on näide asünkroonsest lähenemisviisist.

ComputableFuture töötab suurepäraselt koos Käivitatav kuid mitte Väljakutsetav. Selle asemel on võimalik anda ülesanne, et
ComputableFuture kujul Tarnija.

Vaatame, kuidas ülaltoodu on seotud meie probleemiga.

int[] a1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] a2 = {10, 10, 10, 10, 10, 10, 10, 10, 10, 10};
int[] a3 = {3, 4, 3, 3, 4, 3, 4, 2, 1, 3, 7};

CompletableFuture.supplyAsync(() -> Arrays.stream(a1).sum())
                .thenAccept(System.out::println);

CompletableFuture.supplyAsync(() -> Arrays.stream(a2).sum())
                .thenAccept(System.out::println);

CompletableFuture.supplyAsync(() -> Arrays.stream(a3).sum())
                .thenAccept(System.out::println);

Esimene asi, mis silma torkab, on see, kui palju lühem on see lahendus. Peale selle näeb see ka puhas ja korralik välja.

Ülesanne ValmisTulevik võib anda supplyAsync() meetod, mis võtab Tarnija või runAsync() et
võtab Käivitatav. Tagasikutsumine - kood, mis tuleb käivitada ülesande lõpetamisel - on defineeritud järgmiselt. thenAccept()
meetod.

Järeldused

Java pakub palju erinevaid lähenemisviise samaaegsusele. Selles artiklis me vaevu puudutasime seda teemat.

Sellegipoolest käsitlesime põhitõdesid Teema, Käivitatav, Väljakutsetavja CallableFuture mis on hea mõte
teema edasiseks uurimiseks.

Seotud artiklid

Tarkvaraarendus

9 viga, mida vältida Java programmeerimisel

Milliseid vigu tuleks Java keeles programmeerimisel vältida? Järgnevas teoses vastame sellele küsimusele.

The Codest
Rafal Sawicki Java arendaja
Enterprise & Scaleups lahendused

Õige viis tipp Java arendajate leidmiseks

Ideaalse Java-arendaja leidmine võib olla keeruline ülesanne. Kuna turunõudlus selliste spetsialistide järele kasvab hämmastava kiirusega, võivad olemasolevad allikad talentide otsimiseks mõnikord tunduda...

The Codest
Grzegorz Rozmus Java üksuse juht
Enterprise & Scaleups lahendused

10 Dubai ettevõtet, mida tasub 2020. aastal jälgida

Dubai on Araabia Ühendemiraatide süda, kus tegutsevad üha jõukamad globaalsed ettevõtted ja paljulubavad idufirmad. Paljud võivad uhkustada oma rahvusvahelise edu ja märkimisväärsete toodetega.....

Tuna Pinar
Enterprise & Scaleups lahendused

Kuidas saab Java teie ettevõtet toetada?

Enne kui me alustame, tahaksin teile meelde tuletada üht olulist asja. Java ei ole ainult programmeerimiskeel.

Bartlomiej Kuczynski
Enterprise & Scaleups lahendused

Üks päev programmeerija elus The Codest juures

Võiksite kahtlustada, et programmeerijate töögraafikud ei erine üksteisest. Kuid see ei ole tegelikult tõsi! Igal idufirmal, tarkvaramaja, isegi ettevõttel on oma...

The Codest
Pawel Rybczynski Software Engineer

Tellige meie teadmistebaas ja jääge kursis IT-sektori eksperditeadmistega.

    Meie kohta

    The Codest - rahvusvaheline tarkvaraarendusettevõte, mille tehnoloogiakeskused asuvad Poolas.

    Ühendkuningriik - peakorter

    • Büroo 303B, 182-184 High Street North E6 2JA
      London, Inglismaa

    Poola - kohalikud tehnoloogiakeskused

    • Fabryczna büroopark, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Varssavi, Poola

      The Codest

    • Kodu
    • Meie kohta
    • Teenused
    • Case Studies
    • Tea kuidas
    • Karjäärivõimalused
    • Sõnastik

      Teenused

    • See nõuandev
    • Tarkvaraarendus
    • Backend arendus
    • Frontend arendus
    • Staff Augmentation
    • Backend arendajad
    • Pilveinsenerid
    • Andmeinsenerid
    • Muud
    • QA insenerid

      Ressursid

    • Faktid ja müüdid koostööst välise tarkvaraarenduspartneriga
    • USAst Euroopasse: Miks otsustavad Ameerika idufirmad Euroopasse ümber asuda?
    • Tech Offshore arenduskeskuste võrdlus: Euroopa (Poola), ASEAN (Filipiinid), Euraasia (Türgi).
    • Millised on CTO ja CIOde peamised väljakutsed?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. Kõik õigused kaitstud.

    etEstonian
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch elGreek etEstonian