Prioritățile thread sunt folosite de planificatorul de fire pentru a decide când fiecare fir va fi permis să funcționeze. În teorie, firele cu prioritate ridicată primesc mai mult timp procesor decât cele cu prioritate scăzută. Aproape timpul în care un procesor primește un fir depinde adesea de mai mulți factori, pe lângă prioritatea sa. (De exemplu, modul în care sistemul de operare implementează multitasking poate afecta disponibilitatea relativă a timpului procesorului). Un flux cu prioritate ridicată poate, de asemenea, descărca un flux cu prioritate redusă. De exemplu, atunci când un fir cu prioritate mică rulează și un fir cu prioritate ridicată va continua lucrul întrerupt (datorită suspendării sau așteptării unei operații de intrare / ieșire pentru a finaliza), acesta din urmă descarcă un fir cu prioritate redusă.
Teoretic, firele cu prioritate egală ar trebui să primească acces egal la procesorul central. Dar trebuie să fii atent. Rețineți că Java este proiectat să funcționeze într-o gamă largă de medii. Unele dintre aceste medii realizează că multitaskingul este fundamental diferit de celelalte. Din motive de securitate, firele care au aceeași prioritate trebuie gestionate în mod egal. Acest lucru asigură că toate firele vor putea funcționa într-un mediu de sisteme de operare cu multitasking non-preemptiv. În practică, chiar și în mediile non-preemptive multi-tasking, majoritatea firelor au încă șansa de a executa, deoarece majoritatea firelor se confruntă în mod inevitabil cu situații de blocare, cum ar fi așteptarea I / O. Când se întâmplă acest lucru, firul blocat este suspendat, iar restul firelor pot funcționa. Dar dacă doriți să obțineți o muncă netedă multi-filetată, atunci nu vă bazați pe ea. În plus, unele tipuri de sarcini încarcă puternic procesorul. Astfel de fire capturează procesorul. Fluxurile de acest tip trebuie să fie transmise de la un caz la altul pentru a permite execuția de către un altul.
Pentru a seta prioritatea firului, folosiți metoda setPriority (), care este membru al clasei Thread. Deci, forma sa generală arată:
set final final (nivel int)
Aici, nivelul specifică un nou nivel de prioritate pentru firul apelant. Valoarea nivelului trebuie să se situeze în intervalul de la MIN_PRIORITY la MAX_PRIORITY. În prezent, aceste valori sunt 1 și 10. Pentru a readuce prioritatea la valoarea implicită, specificați NORM_PRIORITY, care este în prezent 5. Aceste priorități sunt definite ca variabile finale statice în clasa Thread.
Puteți obține valoarea curentă a priorității firului apelând metoda getPriority () din clasa Thread, după cum se arată mai jos:
final int getPriority ()
Următorul exemplu prezintă două fire cu priorități diferite care sunt executate pe platformă fără multitasking preemptiv diferit decât pe platforma cu multitasking specificat. Un fir are prioritate două nivele peste normal, așa cum este definit de Thread.NORM_PRIORITY, iar celălalt - două nivele inferioare normale. Fluxurile pornesc și sunt gata de execuție în 10 secunde. Fiecare fir execută o buclă care numără numărul de iterații. După 10 secunde, firul principal oprește ambele fire. Apoi, se afișează numărul de iterații ale bucla pe care fiecare fir a reușit să o execute.
// Demonstrați prioritățile firului.
Clicker de clasă pune în aplicare Runnable long click = 0;
Thread t;
exploatare booleană privată volatilă = adevărată;
clicer public (int p) t = nou subiect (acest lucru);
t.setPrioritatea (p);
>
public void run () în timp ce (execută) faceți clic pe ++;
>
>
void public stop () running = false;
>
public void start () t. începe ();
>
>
clasa HiLoPri public static void principal (String args []) Thread.currentThread ();
setPrioritate (Thread.MAX_PRIORITY);
clicker hi = clicker nou (Thread.NORM_PRIORITY + 2);
clicker lo = clicker nou (Thread.NORM_PRIORITY - 2);
lo.start ();
hi.start ();
încercați Thread.sleep (10000);
>
captură (InterruptedException e) System.out.println ("Principalul thread este întrerupt");
>
lo.stop ();
hi.stop ();
// Așteptați 10 secunde înainte de a întrerupe.
încercați hi.t.join ();
lo.t.join ();
>
captură (InterruptedException e) System.out.println ("Interceptatăexcepție blocată");
>
System.out.println ("Stream cu prioritate redusă:" + lo.click);
System.out.println ("Thread cu prioritate ridicată:" + hi.click);
>
>
De ieșire a acestui program atunci când rulează pe Windows indică faptul că firele au schimbat contextul, deși nu a existat nici o captură procesor forțat și nici blocarea I / O. Firele cu prioritate ridicată au primit cea mai mare parte a timpului procesorului.
Subiect cu prioritate redusă: 4408112
Debit cu prioritate ridicată: 589626904
Desigur, ieșirea exactă generată de acest program depinde de viteza procesorului dvs. și de numărul de sarcini efectuate pe sistem. Când același program este rulat într-un mediu cu multitasking non-preemptiv, se obține un alt rezultat.
Încă o observație despre programul anterior. Rețineți că variabila de funcționare este precedată de cuvântul volatil. Deși volatile este explicată mai detaliat în Capitolul 13, ea este utilizată aici pentru a se asigura că valoarea de funcționare va fi verificată la fiecare pas al iterației buclei:
Fără Java volatile, Java are capacitatea de a optimiza buclă astfel încât să fie creată o copie locală de rulare. Utilizarea volatile previne această optimizare, spunând Java că funcționarea poate fi modificată implicit pentru cod.