A többszálas szál, futtatható

Többszálú programozás lehetővé teszi, hogy külön a megjelenítésére és feldolgozására vonatkozó információk a szám a „könnyű” folyamatok (könnyű folyamatokat), a teljes hozzáférést biztosít mind a különböző módszerek alkalmazása az objektumok és területek. Többszálas elengedhetetlen abban az esetben, ha a GUI reagálnia kell a felhasználói tevékenységek a teljesítménye egy adott információ feldolgozása. Témák kölcsönhatásba léphetnek egymással a fő „szülő” patak, ahonnan elindult.

Példaként néhány folyni az adatszolgáltatásra kötelezett a felületen, amely megvárja, amíg a másik patak, egy fájl letöltését, és egyidejűleg kijelzi egy bizonyos animációt vagy frissíti az állapotjelző sáv. Ezen túlmenően, ez az áramlás megáll egy fájl letöltése folyam, ha megnyomja a „Mégsem”.

Java alkotók adtak a lehetőségét két folyamban: végrehajtásának (végrehajtási) futtatható interfész és kiterjesztés (kiterjedő) Téma osztályban. Kiterjesztése az osztály - ez a módja annak, hogy örökölje a módszerek és változók a szülő osztályban. Ebben az esetben, akkor örököl csak az egyik szülő osztály szál. Ez a korlátozás lehet legyőzni egy Java végrehajtása futtatható felületen. amely a leggyakoribb módja, hogy hozzon létre egy szál.

Előnyök folyni a folyamat

  • áramlik sokkal könnyebb folyamat, mert ehhez kevesebb időt és erőforrásokat;
  • összefüggésben a szálak közötti sokkal gyorsabb, mint a folyamatok közötti;
  • Sokkal könnyebb elérése közötti szálak mint a folyamatok közötti.

A fő téma

Minden java alkalmazás van legalább egy végrehajtási szál. A patak, ahonnan indul a program, az úgynevezett elsődleges. Miután létrehozott folyamat, mint általában, JVM indul végrehajtását főáramnak main () módszer. Ezután ha szükséges, további szálak is fut. A többszálas - két vagy több szál fut egyszerre ugyanazt a programot. A számítógép egy egymagos processzor végre tud hajtani csak egy szál, elosztjuk CPU idő közötti folyamatok és szálak.

Menet osztály

A Thread osztály határozza hét tervezők túlterhelt, számos módszer streaming, és három állandó (flow végrehajtási prioritások).

Konstruktőrök Thread osztály

  • célba - egy példányát az osztály végrehajtására futtatható interfész;
  • neve - a név a keletkező áramlás;
  • csoport - csoportot, amelyhez az adatfolyam.

Példa létrehozásának egy folyam, amely belép a csoport hajtja végre a futtatható interfész, és egy egyedi neve:

Csoportok folyik, amely akkor használható, ha szükséges egyformán kezelni több forrásból. Például több adatfolyamot nyomtatni, és annak szükségességét, hogy szakítsa meg a nyomtatás minden dokumentumot sorban állnak. Ebben az esetben célszerű alkalmazni egy parancsot minden folyamok ugyanabban az időben, nem pedig külön-külön téma. De meg lehet csinálni, ha a hullámok vannak rendelve egy csoportba.

Annak ellenére, hogy a fő téma automatikusan létrejön, akkor is szabályozható. Ehhez létre kell hozni egy szál osztály objektum hívja currentThread ().

Menet osztály módszerek

A leggyakrabban használt módszer a szál osztály áramlásszabályozó:

  • hosszú getId () - megszerzése adatfolyam-azonosítót;
  • Húr getName () - rá a nevét a patak;
  • int getPriority () - megszerzése egy patak prioritást;
  • Állami getState () - Az áramlás állapotban
  • void interrupt () - megszakítás végrehajtását egy szál;
  • logikai isAlive () - ellenőrzi, hogy a szál végrehajtó;
  • logikai isDaemon () - annak ellenőrzése, hogy «Daemon» áramot;
  • void csatlakozni () - várakozás befejezése áramlását;
  • void csatlakozzon (Millis) - elvárás Millis milliszekundum folyás végéig;
  • void értesíti () - «ébredés” külön áramot vár »jel«;
  • void notifyAll () - «ébredés” összes szál vár »jel«;
  • void run () - dob egy áramlás, ha az áramlás jött létre a futtatható interfész;
  • void setDaemon (bool) - Az áramlás vagy a felhasználó «Daemon»;
  • void setPriority (int) - Az áramlás prioritás;
  • void alvás (int) - a szuszpenzió áramlási egy előre meghatározott időt;
  • void start () - áramlás indul.
  • void várakozás () - a szuszpenzió áramlási amíg egy másik szál hívások értesíti () módszer;
  • void várakozás (Millis) - a szuszpenzió áramlási hogy Millis milliszekundum, vagy addig, amíg egy másik szál hívások értesíti () módszer;

Az életciklus-patak

Amikor a program Thread objektum lehet az egyik a négy fő kimondja: „új”, „szorgalmas”, „kivitelezhetetlen” és „passzív”. Amikor egy szál jön létre, megkapja az állam „új» (NEW), és nem fog futni. Átvitele áramlás az „új” a „működőképes» (futtatható) el kell végeznie a start () metódus, ami a run () metódust.

Az áramlás lehet egyik államok megfelelő elemek egymásba ágyazott transzferek statikusan Thread.State:

ÚJ - szál jön létre, de még nem indult;
Futtatható - a szál végrehajtó;
BLOCKED - az áramlás blokkolva;
VÁRAKOZÁS - szál vár az a művelet végén egy másik szál;
TIMED_WAITING - patak várva a végén egy másik szál;
MEGSZŰNT - az áramlás befejeződött.

Felhasználási példa Menet

A példában tekinthető ChickenEgg párhuzamos működése két áram (Egg fő szál és cérna), amelyben van egy vita, hogy „volt, mielőtt a petesejt vagy a csirke?”. Minden szál az agya egy rövid késleltetés után, kialakítva ChickenEgg.getTimeSleep (). A győztes az a szál, amely utoljára beszélt szavát.

Amikor futtatja a programot a következő üzenet jelent meg a konzolon.

Lehetetlen pontosan megjósolni, hogy melyik szál befejezi az utolsó beszélni. A következő alkalommal futtatja a „győztes” változhatnak. Ez annak köszönhető, hogy az úgynevezett „aszinkron kód végrehajtását.” Aszinkron biztosít függetlenséget szálak. Vagy más szóval, a párhuzamos szálak egymástól függetlenek, kivéve azokat az eseteket, ahol az üzleti logika határozza meg attól függően végrehajtására tőkeáramlás az erre a nyelvre.

interfész futtatható

Futtatható felület tartalmaz csak egy módszer Run ():

run () metódus lefut áramlási kezdődik. Meghatározása után a tárgy futtatható továbbításra kerül az egyik szál osztály konstruktőrök.

Példa osztály RunnableExample, végrehajtja az interfész futtatható

Amikor futtatja a programot a következő üzenet jelent meg a konzolon.

Szálszinkronizációt, szinkronizált

A működés során az áramlás gyakran megosztott erőforrások alkalmazások kívül definiált az áramlást. Ha több szálat egyidejűleg kezdődik, hogy a változások a megosztott erőforrás, a program eredményeit is kiszámíthatatlan. Tekintsük a következő példát:

A példa egy megosztott erőforrás formájában CommonObject osztályt, amelyben van az egész számláló mező. Ez a forrás olyan belső osztályban. megteremtése CounterThread áramot növelni a számláló értéke eggyel ciklust. Elején az áramlási számláló mező beállítása 1. befejeződése után az res.counter áramlási értéket egyenlőnek kell lennie 4.

A fő osztály SynchronizedThread.main programot futtatni öt szál. Azaz, minden szál a ciklusban kell növelni az értékét res.counter a 1-4; és így öt alkalommal. De az eredmény a program, amely megjelenik a konzol más lesz:

Azaz, a teljes res.counter források minden munkát patakok egyszerre, felváltva a változó értékét.

E helyzet enyhítése érdekében, meg kell szinkronizálni a patakok. Az egyik módja annak, hogy szinkronizálja szálak a kulcsszóhoz kapcsolódó szinkronizált. szinkronizált üzemeltető határozza meg a blokk kód vagy módszer, amely rendelkezésre kell állnia csak egy szál. Használhatja a szinkronizált az osztályban vannak definiálva szinkronizált módszerekkel vagy blokkokat. De nem lehet használni a szinkronizált változók és attribútumok az osztály definíciója.

Blokkolása az objektum szintű

A következő kód azt mutatja, hogyan kell használni a szinkronizált nyilatkozatot, hogy blokkolja a hozzáférést az objektumhoz.

Lock a módszer és az osztály szintjén

Blokk erőforrásokhoz való hozzáférés lehet szinten a módszert és az osztályt. A következő kód azt mutatja, hogy ha több esetben egy osztály DemoClass futási időben, csak egy szál végezhet demoMethod () módszer, más szálak elérheti az eljárás blokkolva lesz. Erre azért van szükség, ha azt akarjuk, hogy bizonyos források menet biztonságos.

Minden tárgy Java van egy kapcsolódó monitor, amely egyfajta eszköz-e a hozzáférést az objektumhoz. Amikor kódfuttatást eléri a szinkronizált nyilatkozatot. monitor tárgy blokkolja olyan kizárólagos hozzáférést biztosít a blokk kód csak egy patak, hogy elkészítette a zárat. Miután vége kódblokkba, a monitor tárgy felszabadul, és elérhetővé válik a többi patakok.

Néhány fontos megjegyzés, használja szinkronizált

  1. Szinkronizálás Java biztosítja, hogy a két szál nem tudja végrehajtani egy szinkronizált módszert egyidejűleg.
  2. Az üzemeltető csak akkor használja szinkronban a módszerek és a kód blokkokat lehet statikus és nem statikus.
  3. Ha az egyik szál végrehajtása kezdődik szinkronizált módszerrel vagy blokk, ez a technika / egység blokkolva. Amikor az áramlás kilép a szinkronizált módszer vagy JVM egység kinyitja. A zár kiold, akkor is, ha az áramlás elhagyja a szinkronizált eljárás befejezése után semmilyen hibát vagy kivétel.
  4. A szinkronizálás Java egy NullPointerException a kivétel, ha egy tárgy használnak egy szinkronizált blokk nincs definiálva, azaz null.
  5. Szinkronizált módszerek Java további költségeket az alkalmazások teljesítményét. Ezért érdemes használni a szinkronizálást, ha ez feltétlenül szükséges.
  6. Összhangban a leírás a nyelv nem lehet használni a szinkronizált kivitelező, mert eredményez fordítási hibát.

Kölcsönhatás szálak között a Java, várjon, és értesíti

Amikor kölcsönható patakok gyakran szükséges, hogy függessze fel néhány patakok és az azt követő bejelentése befejezése bizonyos intézkedések más forrásból. Például az első adatfolyam akció az eredményétől függ, a második áramlás akciók, és szükség van valahogy, hogy értesítse az első folyam, a második folyam a termelt / befejezett valami munkát. módszereket használnak az ilyen helyzetekre:

  • várjon () - elengedi a monitor, és hozza a hívó szálat várakozó állapotban, amíg, amíg egy másik szál hívások értesíti () módszerrel;
  • értesíti () - folytatja a munkát áramlását, ami várni () metódus hívták korábban;
  • notifyAll () - folytatódik az összes patakok, akik várni () metódus korábban megadta.

Mindezek a módszerek csak hívott egy szinkronizált összefüggésben (szinkronizált blokk vagy módszer).

Vegyük példának a „termelő-fogyasztó-raktár» (producer-Store-Consumer). Bár a gyártó nem látja el a terméket a raktárból, a fogyasztó nem veszi fel. Tegyük fel, hogy a gyártónak meg kell adnia 5 egység egy bizonyos áru. Ennek megfelelően, a fogyasztónak, hogy az összes árut. De ugyanakkor, mind a raktárban nem lehet több, mint 3 db az áruk. Amikor végre ebben a példában a várakozás (), és erről értesíti ().

Class-áruházoldalának

Class Store két szinkronizált mód áruk beszerzése érdekében get (), és tegye az árut hozzá (). Kézhezvételét követően az áru végezzük számláló száma csekket. Ha a termék nem található a raktáron, azaz counter <1, то вызывается метод wait(). который освобождает монитор объекта Store и блокирует выполнение метода get(). пока для этого монитора не будет вызван метод notify() .

Amikor hozzá az árut, és ellenőrzi a készlet mennyiségének a kezét. Ha az állomány több mint 3 egység az áruk, a termékértékesítés fel kell függeszteni, és kéri értesíti () metódus. hogy átadja a vezérlést kap () metódus a teljes while () ciklusban.

Listák osztályok termelő és a fogyasztó

Termelői és fogyasztói osztályok végre a futtatható felületet. run () módszer felülír-. A tervezők ezen osztályok paraméterként megkapja az objektum tárolási. Elején adat objektumok külön áramban a ciklusban nevű put () és a get () Store osztály „add” és „kapni” termék.

Listing Class Kereskedelmi

A fő stream osztály Trade (a módszer fő) objektumokat hoz létre Gyártó-Store-fogyasztói és a Start folyik termelő és a fogyasztó.

Amikor futtatja a programot a következő üzenet jelenik meg a konzolon:

Takarmány démon, démon

Java-alkalmazás szűnik meg, amikor kilép az utolsó menet. Még ha a main () metódus már elkészült, de még nem teljesített flow-k, akkor a rendszer várni fog a befejezés.

Ez a szabály azonban nem vonatkozik az áramlási démonok (démon). Ha kitölti az utolsó normális folyamat áramlás, és már csak démon szálak, akkor kénytelen lesz megszüntetni és végrehajtása az alkalmazás befejeződik. Sokszor nem démon szálak végrehajtásához használt háttér feladatokat, szolgálja az eljárás egész életében.

Állapítsa démon szál éppen elég. Ehhez megkezdése előtt az áramlás oka a módszer setDaemon (igaz). Ellenőrizze, hogy az áramlás egy démon „th lehetséges módszer hívás isDaemon (). Mint egy példa segítségével démon-áramlás lehet tekinteni egy osztály Trade, amely a következő formában:

Lehet kísérletezni a saját démon-flow meghatározása az egyik osztály (termelő, fogyasztó), illetve mindkét osztályban, és látom, hogy a rendszer (JVM) fog viselkedni.

A végrehajtási választani?

Miért van szükség kétféle threading, és néhány közülük, és mikor kell használni? A válasz egyszerű. Végrehajtás futtatható felületet használják olyan esetekben, amikor az osztály már örökli a szülő osztály, és lehetővé teszi, hogy kiterjesszék a szál osztályban. Emellett jó formában a java programozási tartják, hogy hajtsák végre a felület. Ez annak a ténynek köszönhető, hogy a java lehet örökletes csak az egyik szülő osztályban. Így örökli a Thread osztály. lehetetlen, hogy örökölje minden más osztályba.

Bővítése a Szál osztályba kell használni, ha szükséges, felülírva más módszerek egy osztály eltekintve run () módszer.

letöltés példák

A fenti példák az oldalon threading és szálszinkronizációt formájában az Eclipse projekt letölthető itt (14KB).