Kokie yra pagrindiniai derliaus naudojimo būdai () ir kaip jis skiriasi nuo prisijungimo () ir nutraukimo ()?

Aš truputį supainioti apie yield() metodo naudojimą Java, ypač žemiau pateiktame kodo pavyzdyje. Aš taip pat perskaičiau, kad derlius () naudojamas siekiant išvengti sriegio vykdymo.

Mano klausimai yra:

  • Manau, kad toliau pateikiamas kodas sukelia tą pačią išvadą tiek naudodamas yield() , tiek nesant. Ar tai tiesa?

  • Kokie yra pagrindiniai yield() naudojimo būdai yield() ?

  • Kaip yield() skiriasi nuo join() ir interrupt() metodų?

Kodo pavyzdys:

 public class MyRunnable implements Runnable { public static void main(String[] args) { Thread t = new Thread(new MyRunnable()); t.start(); for(int i=0; i<5; i++) { System.out.println("Inside main"); } } public void run() { for(int i=0; i<5; i++) { System.out.println("Inside run"); Thread.yield(); } } } 

Tą pačią produkciją gaunu naudojant aukščiau esantį kodą su ir nenaudojant yield() :

 Inside main Inside main Inside main Inside main Inside main Inside run Inside run Inside run Inside run Inside run 
67
08 авг. nustatyti chinchu 08 rug . 2011-08-08 12:01 '11, 12:01 PM 2011-08-08 12:01
@ 9 atsakymai

Šaltinis: http://www.javamex.com/tutorials/threads/yield.shtml

„Windows“

Thread.yield() Hotspot“, „ Thread.yield() darbai keičiami tarp „Java 5“ ir „Java 6“.

„Java 5“ programoje „ Thread.yield() skambinama „Windows API“ „ Sleep(0) skambučiu. Tai turi ypatingą efektą - išvalyti esamą srauto kvantą ir įdėti jį į eilės pabaigą prioritetiniam lygiui . Kitaip tariant, visi vykdomieji siūlai, turintys tą patį prioritetą (ir tuos, kurie turi aukštesnį prioritetą), galės pradėti, kol kitas temas turės kitą nurodytą procesoriaus laiką. Kai jis yra perkeliamas, jis grįš visapusiškai pilną kvantą , bet „neperduos“ jokio likusio kiekio nuo derliaus momento. Šis elgesys šiek tiek skiriasi nuo nulinės miego, kai miegantis siūlas paprastai praranda 1 kvantinę vertę (iš tiesų, 1/3 10 arba 15 ms).

„Java 6“ atveju šis elgesys pasikeitė. Šiuo metu „Hotspot Thread.yield() virtualioji mašina, naudojama naudojant „ SwitchToThread() API skambutį, yra „Windows SwitchToThread() . Šis kvietimas verčia dabartinį sriegį eiti dabartiniu laiku , bet ne visą jo kvantą. Tai reiškia, kad, priklausomai nuo kitų sričių prioritetų, dabartinis sriegis gali būti suplanuotas vienam pertraukimui po laikotarpio . (Išsamesnės informacijos ieškokite sriegių skilties skiltyje. Laiko sąrašo informacija.)

Linux

„Linux“ sistemoje „Hotspot“ tik skambina pagal sched_yield() . Šio kvietimo pasekmės yra šiek tiek kitokios ir galbūt sunkesnės nei „Windows“:

  • gautas siūlas nepriims kito procesoriaus fragmento, kol visi kiti siūlai neturi CPU ;
  • (bent jau branduolio 2.6.8 ir vėlesnėse versijose) faktas, kad siūlai yra pateikiami, netiesiogiai atsižvelgiama į planatoriaus heuristiką, susijusią su jo naujausiu CPU priskyrimu, taigi, netiesiogiai, siūlai, su sąlyga, kad jis gali būti pateiktas ateityje daugiau CPU.

(Daugiau informacijos apie prioritetus ir planavimo algoritmus žr. Skyriuje „ Siūlų planavimas“ .)

Kada naudoti yield() ?

Sakyčiau beveik niekada . Jo elgesys nėra standartinis ir, kaip taisyklė, geriausius būdus, kaip atlikti užduotis, gali tekti atlikti su derliu ():

  • Jei bandote naudoti tik dalį procesoriaus , galite tai padaryti labiau valdomu būdu, įvertindami, kiek CPU yra siūlai, naudojami paskutiniame apdorojimo fragmente, tada užmigkite tam tikrą laiką, kad kompensuotumėte: žr. Miego () metodą;
  • jei tikitės, kad procesas ar ištekliai bus užbaigti arba taptų prieinami, tai yra veiksmingesni būdai tai padaryti, pavyzdžiui, naudodami prisijungimą (), kad palauktumėte kito siūlo užbaigimą, naudodami laukimo / pranešimo mechanizmą, kad vienas siūlas galėtų signalizuoti kitam, kad užduotis baigta arba idealiu atveju, naudojant vieną iš „Java 5“ sukurtų sutapimų, pvz., Semaforo arba eilės blokavimo .
73
08 авг. atsakymą pateikė Sathwick 08 rug . 2011-08-08 12:07 '11, 12:07, 2011-08-08 12:07

Matau, kad klausimas buvo vėl suaktyvintas dosnumu, dabar paklausiu, koks yra praktinis naudos panaudojimas. Aš duosiu pavyzdį iš savo patirties.

Kaip žinote, yield verčia skambinančią temą atsisakyti procesoriaus, su kuriuo jis dirba, kad būtų galima suplanuoti kitą temą. Tai naudinga, kai dabartinis siūlelis jau baigė darbą, tačiau nori greitai grįžti į eilės priekį ir patikrinti, ar pasikeitė bet kokia būklė. Kaip tai skiriasi nuo sąlyginio kintamojo? yield leidžia siūlui grįžti į greitesnę būseną. Laukdami būsenos kintamojo, sriegis pristabdo ir turi palaukti, kol kitas pokytis parodys jo tęstinumą. yield iš esmės sako: "Leiskite pradėti kitą temą, bet leiskite man grįžti į darbą labai greitai, nes tikiuosi, kad mano būklė labai greitai pasikeis." Tai rodo, kad verpimas yra užimtas, kai būklė gali greitai pasikeisti, tačiau srauto sustabdymas sukels puikų rezultatą.

Bet pakankamai babbling, čia yra konkretus pavyzdys: lygiagretus modelis su bangos priekiniu. Pagrindinis šios problemos pavyzdys yra atskirų „salų“ 1s skaičiavimas dvimatėje matricoje, užpildytoje 0s ir 1s. „Sala“ - tai ląstelių grupė, esanti vienas šalia kito vertikaliai arba horizontaliai:

 1 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 1 1 

Čia mes turime dvi 1-osios salos: viršutiniame kairiajame ir apatiniame dešiniajame kampe.

Paprastas sprendimas yra pirmasis leidimas per visą masyvą ir 1 reikšmes pakeisti papildomu skaitikliu, kad kiekvienas 1 būtų pakeistas sekos numeriu sekančia tvarka:

 1 0 0 0 2 3 0 0 0 0 0 4 0 0 5 6 0 0 7 8 

Kitame etape kiekviena vertė pakeičiama minimalia verte tarp jos ir jos kaimyninių reikšmių:

 1 0 0 0 1 1 0 0 0 0 0 4 0 0 4 4 0 0 4 4 

Dabar mes galime lengvai nustatyti, kad turime dvi salas.

Dalis, kurią norime paleisti lygiagrečiai, yra žingsnis, kuriuo apskaičiuojamos minimalios. Nesileidžiant į detales, kiekvienas sriegis gauna eilutes kintančiu būdu ir remiasi vertėmis, apskaičiuotomis pagal viršutinę eilutę apdorojančią siūlą. Taigi, kiekvienas siūlas turėtų šiek tiek atsilikti nuo siūlų, apdorojančių ankstesnę eilutę, bet taip pat turi išlaikyti per protingą laiką. Išsamesnė informacija ir įgyvendinimas pateikiami šiame dokumente . Atkreipkite dėmesį į sleep(0) , kuris yra daugiau ar mažiau lygus C yield .

Tokiu atveju yield panaudotas tam, kad kiekvienas siūlas būtų sustabdytas pakaitomis, bet kadangi kito eilutės siūlų apdorojimas bus labai greitas, būklės kintamasis bus blogas pasirinkimas.

Kaip matote, yield yra gana subtilus optimizavimas. Pavyzdžiui, naudokite jį neteisingoje vietoje. laukiant, kol pasikeis pokyčiai, retai bus per daug CPU.

Atsiprašau už ilgą babbling, tikiuosi, kad aš aiškiai.

24
28 июля '14 в 19:11 2014-07-28 19:11 Atsakymą pateikia Tudoras liepos 28 d., 14 val., 19:11, 2014-07-28 19:11

Apie skirtumus tarp yield() , interrupt() ir join() - apskritai, ne tik „Java“:

  • derlius Pažodžiui, „duoti“ reiškia paleisti, perduoti, perduoti. Prisidedanti siūlai informuoja operacinę sistemą (arba virtualią mašiną), kuri yra pasirengusi leisti kitiems siūlams. Tai rodo, kad jis nieko nedaro labai kritiškai. Tai tik užuomina, bet ne garantuotas efektas.
  • prisijungti . Kai keletas sriegių prisijungia prie konkretaus deskriptoriaus ar simbolio ar subjekto, jie visi laukia, kol visi kiti atitinkami siūlai bus užbaigti (visiškai arba prieš savo atitinkamą sujungimą). Tai reiškia, kad siūlai buvo baigti visomis savo užduotimis. Tada kiekvienas iš šių srautų gali planuoti kito darbo tęstinumą, galėdamas daryti prielaidą, kad visos šios užduotys iš tiesų yra baigtos. (Negalima painioti su SQL ryšiais!)
  • nutraukti Vieną temą jis naudoja „išstumti“ kitą siūlą, kuris miega arba laukia, arba prisijungia - taip, kad jis ir toliau dirbtų dar kartą, galbūt nurodydamas, kad jis buvo nutrauktas (negali būti painiojama su aparatinės įrangos pertraukomis!)

Visų pirma, „Java“, žr

10
04 апр. atsakymas duotas einpoklum 04 balandžio. 2013-04-04 22:24 '13, 22:24 pm 2013-04-04 22:24

Pirma, faktinis aprašymas

Sukelia laikinai vykdomą siūlų objektą laikinai sustabdyti ir leisti kitiems siūlams atlikti.

Dabar labai tikėtina, kad jūsų pagrindinis siūlas bus užblokuotas penkis kartus, kol bus vykdomas naujos siūlų run metodas, todėl visi yield skambučiai bus vykdomi tik po to, kai bus įvykdyta pagrindinio gijos kilpa.

join sustabdys dabartinį siūlą, kol vykdomas įvykdomas srautas su join() .

interrupt nutrauks sriegį, kuriuo jis yra skambinamas, sukeldamas pertrauką .

yield leidžia pereiti prie kitų sričių, todėl šis gija nevartoja viso procesoriaus naudojimo proceso.

8
08 авг. atsakymas pateiktas MByD 08 rug . 2011-08-08 12:05 '11, 12:05, 2011-08-08 12:05

Kokie yra pagrindiniai derliaus naudojimo būdai ()?

Išeiga nurodo procesoriui, kad galite sustabdyti dabartinį sriegį ir pradėti vykdyti temas su aukštesniu prioritetu. Kitaip tariant, mažesnės prioritetinės vertės priskyrimas dabartiniam sriegiui palieka daugiau svarbių sričių.

Manau, kad toliau pateikiamas kodas sukelia tokią pačią išvadą, kai naudojamas derlius () ir jo nėra. Ar tai tiesa?

NE, jie suteiks skirtingų rezultatų. Be derliaus (), kai gija bus kontroliuojama, ji vienu metu vykdys „Inside run“ kilpą. Tačiau, kai išeina (), kai gija bus kontroliuojama, ji vieną kartą atspausdins „Inside run“ ir tada perkelia valdiklį į kitą sriegį, jei yra. Jei siūlelis laukia, šis gija vėl bus atnaujintas. Todėl kiekvieną kartą, kai vykdomas vidinis darbas, jis ieškos kitų temų, kurios bus paleistos, o jei siūlelis nėra, dabartinis siūlelis ir toliau bus rodomas.

Kaip derliaus () metodas skiriasi nuo prisijungimo () ir nutraukimo () metodų?

derlius () skirtas kitoms svarbioms temoms pateikti, prisijungti () laukia, kol bus įvykdytas kitas temas, ir nutraukti () yra nutraukti dabartinį vykdomąjį siūlą, kad būtų daroma kita.

2
03 авг. atsakymas pateikiamas abbas 03 rug. 2014-08-03 13:01 '14 at 13:01 2014-08-03 13:01

Thread.yield() pereina iš „Vykdyti“ būsenos į „Paleidžiamą“ būseną. Pastaba Tai nesukelia sriegio perėjimo prie būsenos būsenos.

1
05 мая '17 в 20:55 2017-05-05 20:55 atsakymą pateikė Prashant Gunjal 05 gegužės 17 d., 20:55, 2017-05-05 20:55

„Thread.yield“ ()

Kai vadiname „Thread.yield“ () metodą, siūlų planuotojas išsaugo šiuo metu veikiančią siūlą į „Runnable“ būseną ir pasirenka kitą sriegį, kurio prioritetas yra vienodas arba didesnis. Jei nėra vienodo ir aukštesnio prioriteto srauto, jis nukreipia skambučio srautą (). Atminkite, kad derlingumo metodas nepateikia siūlų lauke „Palaukite“ arba „Užblokuotas“. Jis gali srautą atlikti tik iš „Running State“ į „Runnable State“.

Prisijunkite ()

Kai prisijungimas yra vadinamas sriegio egzemplioriumi, šis pokalbis informuos dabartinį sriegio vykdymą, kad jis lauktų, kol bus užbaigtas prisijungimo srautas. Ryšys naudojamas tokiose situacijose, kai bus atlikta užduotis, kuri turi būti atlikta prieš užbaigiant dabartinę užduotį.

0
12 мая '14 в 13:14 2014-05-12 13:14 atsakymą pateikė Prashant Kumar gegužės 12 d. 14 val. 14:14 2014-05-12 13:14

1.Naudojant derlingumo metodą toliau pateiktame kode, gaunama produkcija. Ar tai tiesa?

Šiuo atveju teisinga išvada nenurodyta, todėl viskas yra teisinga.

2. Paprastai pagrindinis išeigos panaudojimas ()

Ji beveik niekada nebuvo naudojama, jau nekalbant apie „pirminį naudojimą“. Aš niekada nenaudojau derliaus () metodo jokioje platformoje, ir aš juos naudojiau už mane daugiau nei 20 metų, o per šį laikotarpį darau gana rimtą sistemos programavimą.

3. Kaip skiriasi nuo prisijungimo () ir nutraukimo () metodų

Tai skiriasi tuo, kad tai nėra tas pats dalykas. Klausimas yra visiškai beprasmis.

0
08 авг. atsakymą pateikė ejp 08 rug . 2011-08-08 13:01 '11 - 01: 01 pm 2011-08-08 13:01

išeiga () daugiausia naudojama laikant daugiapakopę programą.

visi šie metodų skirtumai - išeiga () perkelia siūlą į laikiklį, kai įvykdomas kitas sriegis ir grąžinamas po to, kai užbaigiamas šis pokalbis, prisijungia () pradės sriegių vykdymą iki galo ir kitą temą, prasidedantį po to, kai baigėsi šis poklasis, nutraukimas () sustabdys siūlų vykdymą tam tikrą laiką.

-2
01 авг. K.Hughley atsakymas 2014-08-01 23:43 '14, 23:43 2014-08-01 23:43