Programavimas

„Java 101“: „Java“ gijų supratimas. 4 dalis: Gijų grupės, nepastovumas ir gijų lokalūs kintamieji

Šio mėnesio „Java 101“ užbaigia gijų seriją, sutelkdamas dėmesį į gijų grupes, nepastovumą, gijos lokaliuosius kintamuosius, laikmačius ir ThreadDeath klasė.

Suprasti „Java“ gijas - perskaitykite visą seriją

  • 1 dalis. Pristatome siūlus ir bėgimus
  • 2 dalis. Siūlų sinchronizavimas
  • 3 dalis: Gijos planavimas, laukimas / pranešimas ir gijos nutraukimas
  • 4 dalis. Gijų grupės, nepastovumas, vietiniai siūlų kintamieji, laikmačiai ir gijų mirtis

Siūlų grupės

Tinklo serverio programoje viena gija laukia ir priima kliento programų užklausas vykdyti, pavyzdžiui, duomenų bazės operacijas ar sudėtingus skaičiavimus. Gija paprastai sukuria naują giją užklausai tvarkyti. Priklausomai nuo užklausos apimties, vienu metu gali būti daug skirtingų gijų, apsunkinančių gijų valdymą. Norėdami supaprastinti gijų valdymą, programos organizuoja savo gijas siūlų grupėsjava.lang.ThreadGroup objektai, kurie grupuoja susijusias gijas ' Siūlas (ir Siūlas poklasio) objektai. Pavyzdžiui, jūsų programa gali naudoti „ThreadGroup“ sugrupuoti visus spausdinimo siūlus į vieną grupę.

Pastaba: Kad diskusija būtų paprasta, aš siūlau gijų grupes taip, tarsi jos organizuotų gijas. Iš tikrųjų gijų grupės organizuojasi Siūlas (ir Siūlas poklasis) objektai, susieti su gijomis.

„Java“ reikalinga kiekviena gija ir kiekviena gijų grupė - išsaugokite šaknų gijų grupę, sistema- prisijungti prie kitos temų grupės. Šis išdėstymas veda prie hierarchinės gijų grupės struktūros, kurią toliau pateiktas paveikslas iliustruoja programos kontekste.

Figūros struktūros viršuje yra sistema siūlų grupė. JVM sukurtas sistema grupė organizuoja JVM gijas, kurios nagrinėja objektų užbaigimą ir kitas sistemos užduotis, ir yra programos hierarchinės gijų grupės struktūros šaknų grupė. Šiek tiek žemiau sistema yra JVM sukurtas pagrindinis siūlų grupė, kuri yra sistemapogrupio grupė (trumpai - pogrupis). pagrindinis yra bent viena gija - JVM sukurta pagrindinė gija, vykdanti baito kodo instrukcijas pagrindinis () metodas.

Žemiau pagrindinis grupė gyvena 1 pogrupis ir 2 pogrupis pogrupiai, programos sukurti pogrupiai (kuriuos sukuria paveikslo programa). Be to, 1 pogrupis grupuojamos trys programos sukurtos gijos: sriegis 1, sriegis 2ir 3 sriegis. Priešingai, 2 pogrupis sugrupuoja vieną programos sukurtą giją: mano gija.

Dabar, kai žinote pagrindus, pradėkime kurti gijų grupes.

Sukurkite gijų grupes ir susiekite gijas su tomis grupėmis

„ThreadGroup“ klasės SDK dokumentai atskleidžia du konstruktorius: „ThreadGroup“ (eilutės pavadinimas) ir „ThreadGroup“ („ThreadGroup“ tėvas, eilutės pavadinimas). Abu konstruktoriai sukuria gijų grupę ir suteikia jai pavadinimą vardas parametras nurodo. Konstruktoriai skiriasi pasirinkdami, kuri siūlų grupė tarnauja kaip naujai sukurtai siūlų grupei. Kiekviena gijų grupė, išskyrus sistema, turi turėti pirminę gijų grupę. Dėl „ThreadGroup“ (eilutės pavadinimas), pagrindinis yra siūlomos gijos gijų grupė „ThreadGroup“ (eilutės pavadinimas). Pavyzdžiui, jei skambina pagrindinė gija „ThreadGroup“ (eilutės pavadinimas), naujai sukurtoje gijų grupėje yra pagrindinės gijos grupė -pagrindinis. Dėl „ThreadGroup“ („ThreadGroup“ tėvas, eilutės pavadinimas), tėvai yra ta grupė tėvas nuorodos. Šis kodas parodo, kaip naudoti šiuos konstruktorius kuriant gijų grupių porą:

public static void main (String [] args) {ThreadGroup tg1 = nauja ThreadGroup ("A"); „ThreadGroup“ tg2 = nauja „ThreadGroup“ (tg1, „B“); }

Aukščiau pateiktame kode pagrindinė gija sukuria dvi gijų grupes: A ir B. Pirma, sukuriama pagrindinė gija A skambindami „ThreadGroup“ (eilutės pavadinimas). tg1nurodytos gijos grupės tėvai yra pagrindinis nes pagrindinis yra pagrindinė gijos gijų grupė. Antra, sukuria pagrindinę giją B skambindami „ThreadGroup“ („ThreadGroup“ tėvas, eilutės pavadinimas). tg2nurodytos gijos grupės tėvai yra A nes tg1nuoroda kaip argumentas perduodama „ThreadGroup“ (tg1, „B“) ir A bendrauja su tg1.

Patarimas: Kai jums nebereikia hierarchijos „ThreadGroup“ objektai, skambinkite „ThreadGroup“'s niekinis sunaikinimas () metodas naudojant nuorodą į „ThreadGroup“ objektas tos hierarchijos viršuje. Jei viršuje „ThreadGroup“ objekte ir visuose pogrupio objektuose trūksta gijų objektų, sunaikinti () paruošia tuos siūlų grupės objektus šiukšlių surinkimui. Priešingu atveju sunaikinti () meta an „IllegalThreadStateException“ objektas. Tačiau, kol nepanaikinsite nuorodos į viršų „ThreadGroup“ objekto (darant prielaidą, kad lauko kintamajame yra ši nuoroda), šiukšlių surinkėjas negali surinkti to objekto. Nurodydami viršutinį objektą, galite nustatyti, ar anksčiau buvo skambinta į sunaikinti () metodas skambindamas „ThreadGroup“'s loginis yra sunaikintas () metodas. Šis metodas grąžinamas, jei sunaikinta gijų grupės hierarchija.

Savaime siūlų grupės nenaudingos. Kad būtų naudinga, jie turi grupuoti gijas. Grupuojate gijas į gijų grupes perduodami „ThreadGroup“ nuorodos į tinkamas Siūlas konstruktoriai:

„ThreadGroup“ tg = nauja „ThreadGroup“ („2 pogrupis“); Siūlas t = naujas siūlas (tg, „mano siūlas“);

Pirmiau pateiktas kodas pirmiausia sukuria 2 pogrupis grupė su pagrindinis kaip tėvų grupė. (Manau, kad pagrindinė gija vykdo kodą.) Kitas kodas sukuria a mano gijaSiūlas objektas 2 pogrupis grupė.

Dabar sukurkime programą, kuri sukuria mūsų figūros hierarchinę gijų grupės struktūrą:

Sąrašas 1. ThreadGroupDemo.java

// ThreadGroupDemo.java klasė ThreadGroupDemo {public static void main (String [] argumentai) {ThreadGroup tg = nauja ThreadGroup ("1 pogrupis"); Siūlas t1 = naujas siūlas (tg, "siūlas 1"); Gija t2 = nauja gija (tg, "2 sriegis"); Gija t3 = nauja gija (tg, "3 sriegis"); tg = nauja „ThreadGroup“ („2 pogrupis“); Gija t4 = nauja gija (tg, „mano gija“); tg = Thread.currentThread () .getThreadGroup (); int agc = tg.activeGroupCount (); System.out.println ("Aktyvios gijų grupės" + tg.getName () + "gijų grupėje:" + agc); tg.list (); }}

„ThreadGroupDemo“ sukuria atitinkamą gijų grupę ir gijų objektus, kad atspindėtų tai, ką matote aukščiau esančiame paveikslėlyje. Norėdami įrodyti, kad 1 pogrupis ir 2 pogrupis grupės yra pagrindinistik pogrupiai, „ThreadGroupDemo“ daro taip:

  1. Gauna nuorodą į pagrindines gijas „ThreadGroup“ prieštarauti skambinant Siūlasstatinis currentThread () metodas (kuris pateikia nuorodą į pagrindines gijas Siūlas objektas), po kurio eina Siūlas's „ThreadGroup“ getThreadGroup () metodas.
  2. Skambučiai „ThreadGroup“'s int activeGroupCount () metodas ką tik grąžintam „ThreadGroup“ nuoroda, jei norite pateikti aktyvių grupių įvertinimą pagrindinės gijos gijų grupėje.
  3. Skambučiai „ThreadGroup“'s Eilutė „getName“ () metodas grąžinti pagrindinės gijos gijų grupės pavadinimą.
  4. Skambučiai „ThreadGroup“'s negaliojantis sąrašas () būdas spausdinti ant standartinio išvesties įrenginio išsamią informaciją apie pagrindinio gijos gijų grupę ir visus pogrupius.

Paleidus, „ThreadGroupDemo“ rodomas toks išvestis:

Aktyvios gijų grupės pagrindinėje gijų grupėje: 2 java.lang.ThreadGroup [name = main, maxpri = 10] Thread [main, 5, main] Thread [Thread-0,5, main] java.lang.ThreadGroup [name = subgroup 1, maxpri = 10] Gija [gija 1,5, 1 pogrupis] Gija [gija 2,5, 1 pogrupis] Gija [gija 3,5, 1 pogrupis] java.lang.ThreadGroup [vardas = 2 pogrupis, maxpri = 10 ] Gija [mano gija, 5, 2 pogrupis]

Rezultatas, kuris prasideda Siūlas rezultatai iš sąrašas ()vidiniai skambučiai Siūlas's toString () metodą, išvesties formatą, kurį aprašiau 1 dalyje. Kartu su ta išvestimi matote išvestį, prasidedančią java.lang.ThreadGroup. Ta išvestis identifikuoja gijų grupės pavadinimą ir didžiausią prioritetą.

Prioriteto ir gijų grupės

Maksimalus gijų grupės prioritetas yra didžiausias prioritetas, kurį gali pasiekti jos gijos. Apsvarstykite jau minėtą tinklo serverio programą. Toje programoje gija laukia ir priima kliento programų užklausas. Prieš tai atlikdami „wait-for / accept-request“ gija pirmiausia gali sukurti gijų grupę, kurios maksimalus prioritetas yra žemiau tos gijos prioriteto. Vėliau, kai gaunama užklausa, „wait-for / accept-request“ gija sukuria naują giją, atsakančią į kliento užklausą, ir prideda naują giją prie anksčiau sukurtos gijų grupės. Naujos gijos prioritetas automatiškai sumažėja iki maksimalaus gijų grupės. Tokiu būdu laukimo / priėmimo-užklausos gija dažniau reaguoja į užklausas, nes ji vykdoma dažniau.

„Java“ priskiria maksimalų prioritetą kiekvienai gijų grupei. Kai kuriate grupę, „Java“ gauna tą prioritetą iš savo pirminės grupės. Naudokite „ThreadGroup“'s void setMaxPriority (int prioritetas) metodas vėliau nustatyti maksimalų prioritetą. Jokių gijų, kurias įtraukiate į grupę nustatę maksimalų prioritetą, prioritetas negali viršyti didžiausio. Bet kuri aukštesnio prioriteto gija prisijungus prie gijų grupės automatiškai sumažėja. Tačiau, jei naudojate setMaxPriority (int prioritetas) Norėdami sumažinti maksimalų grupės prioritetą, visos grupės, pridėtos prie grupės prieš tą metodo iškvietimą, išsaugo savo pirminius prioritetus. Pvz., Jei pridėsite 8 prioriteto giją prie maksimalaus 9 prioriteto grupės ir tada sumažinsite šios grupės maksimalų prioritetą iki 7, 8 prioriteto gija išliks 8 prioritetu. Bet kuriuo metu galite nustatyti maksimalų gijų grupės prioritetą paskambinę „ThreadGroup“'s int getMaxPriority () metodas. Norėdami pademonstruoti prioritetų ir gijų grupes, aš parašiau „MaxPriorityDemo“:

Sąrašas 2. „MaxPriorityDemo.java“

// MaxPriorityDemo.java klasė MaxPriorityDemo {public static void main (String [] args) {ThreadGroup tg = new ThreadGroup ("A"); System.out.println ("tg maksimalus prioritetas =" + tg.getMaxPriority ()); Gija t1 = nauja gija (tg, "X"); System.out.println ("t1 prioritetas =" + t1.getPriority ()); t1.setPriority (gija.NORM_PRIORITY + 1); System.out.println ("t1 prioritetas po setPriority () =" + t1.getPriority ()); tg.setMaxPriority (siūlas.NORM_PRIORITY - 1); System.out.println ("tg maksimalus prioritetas po setMaxPriority () =" + tg.getMaxPriority ()); System.out.println ("t1 prioritetas po setMaxPriority () =" + t1.getPriority ()); Gija t2 = nauja gija (tg, "Y"); System.out.println ("t2 prioritetas =" + t2.getPriority ()); t2.setPriority (gija.NORM_PRIORITY); System.out.println ("t2 prioritetas po setPriority () =" + t2.getPriority ()); }}

Paleidus, „MaxPriorityDemo“ sukuria tokią produkciją:

tg didžiausias prioritetas = 10 t1 prioritetas = 5 t1 prioritetas po setPriority () = 6 tg didžiausias prioritetas po setMaxPriority () = 4 t1 prioritetas po setMaxPriority () = 6 t2 prioritetas = 4 t2 prioritetas po setPriority () = 4

Siūlų grupė A (kuris tg nuorodos) prasideda didžiausiu prioritetu (10) kaip didžiausiu. Siūlas X, kurio Siūlas objektas t1 nuorodas, prisijungia prie grupės ir gauna 5 prioritetus. Mes pakeičiame tos gijos prioritetą į 6, kuris pavyksta, nes 6 yra mažesnis nei 10. Vėliau mes skambiname setMaxPriority (int prioritetas) sumažinti maksimalų grupės prioritetą iki 4. Nors siūlas X išlieka 6 prioritetu, naujai pridėta Y gija gauna 4 prioritetą. Galiausiai, bandymas padidinti siūlą Y5 prioritetas nepavyksta, nes 5 yra didesnis nei 4.

Pastaba:setMaxPriority (int prioritetas) automatiškai koreguoja maksimalų gijų grupės pogrupių prioritetą.

Be to, kad naudojate gijų grupes, norėdami apriboti gijų prioritetą, galite atlikti kitas užduotis, skambindami įvairiais „ThreadGroup“ metodai, taikomi kiekvienos grupės gijai. Metodai apima anuliuoti sustabdymą (), negaliojantis atnaujinti (), negaliojantis sustojimas ()ir negaliojantis pertraukimas (). Kadangi „Sun Microsystems“ nebenaudojo pirmųjų trijų metodų (jie yra nesaugūs), mes tik nagrinėjame nutraukti ().

Nutraukite gijų grupę

„ThreadGroup“'s nutraukti () metodas leidžia gijai nutraukti konkrečios gijų grupės gijas ir pogrupius. Ši metodika būtų tinkama tokiu atveju: Pagrindinė jūsų programos gija sukuria kelias gijas, kurių kiekviena atlieka darbo vienetą. Kadangi visos gijos turi užpildyti atitinkamus darbo vienetus, kad bet kuri gija galėtų ištirti rezultatus, kiekviena gija laukia baigusi savo darbo vienetą. Pagrindinė gija stebi darbo būseną. Kai laukia visos kitos gijos, iškviečiama pagrindinė gija nutraukti () nutraukti kitų gijų laukimą. Tada tos gijos gali ištirti ir apdoroti rezultatus. 3 sąrašas rodo gijų grupės pertraukimą:

Sąrašas 3. InterruptThreadGroup.java

// „InterruptThreadGroup.java“ klasė „InterruptThreadGroup“ {public static void main (String [] args) {MyThread mt = new MyThread (); mt.setName ("A"); mt.start (); mt = nauja „MyThread“ (); mt.setName ("B"); mt.start (); pabandykite {Thread.sleep (2000); / / Palaukite 2 sekundes }} klasė „MyThread“ pratęsia „Thread“ {public void run () {synchronized ("A") {System.out.println (getName () + "tuoj lauksi".); pabandykite {"A" .palaukite (); } gaudyti (InterruptedException e) {System.out.println (getName () + "nutrauktas"); } System.out.println (getName () + "baigiasi"); }}}
$config[zx-auto] not found$config[zx-overlay] not found