Documente Academic
Documente Profesional
Documente Cultură
Un prim mod de a crea i lansa n executare fire este oferit de clasa Thread
din pachetul java.lang:
public class Thread extends Object implements Runnable
cmpuri
constructori
alte metode
Crearea i lansarea n executare a unui fir se face astfel:
2
Observaii:
- modelul este independent de numrul real de procesoare;
- factorul aleator face ca executri diferite ale aceluiai program (ce folosete fire
de executare) pentru aceleai date de intrare pot conduce la rezultate diferite.
Cnd metoda run se termin, se termin i firul care a invocat-o. Un program
se termin atunci cnd se termin toate firele de executare lansate din cadrul su.
Exemplul 1. Programul urmtor lanseaz dou fire de executare i n
continuare tiprete 200 de '0'; cele dou fire tipresc cte 200 de '1', respectiv de
'2'. Ca urmare a utilizrii modelului aleator, la fiecare executare vor aprea 200 de
'0', 200 de '1' i 200 de '2', n diferite ordini.
class Tip extends Thread {
int i;
Tip(int i) { this.i = i; }
class Fire {
public static void main(String[] args) {
Tip Ob1 = new Tip(1), Ob2 = new Tip(2);
Ob1.start(); Ob2.start();
for(int k=0; k<200; k++) System.out.print("0 ");
}
}
Observaie. Dac nu s-ar apela la convenia de mai sus i Ob1 i Ob2 ar invoca
metoda run, atunci firul care invoc aceast metoda nu i-ar continua activitatea i ar
atepta ca cele dou obiecte s termine de executat metoda run, deci s-ar renuna la
esena firelor: executarea lor concurent! Concret, vor aprea 200 de '1', urmai de
200 de '2' i de 200 de '0'.
Observaie. Firul care lanseaz un nou fir nu are drepturi suplimentare: de
exemplu se poate termina naintea celui pe care l lanseaz.
Interfaa Runnable
3
T.start();
. . .
n aceast form apare clar faptul c obiectul Ob nu este ocupat dup pornirea
firului.
aciunea:
try {
Ob1.join(); Ob2.join();
}
catch(InterruptedException e) { }
class P1 {
public static void main(String[] w) {
Scanner sc = new Scanner(System.in);
Tip Ob = new Tip(); Ob.start();
while ( sc.next().charAt(0) != 'q' );
Ob.terminare(); System.out.println("main");
}
}
4
Acest exemplu arat c obiectul pe baza cruia este lansat un fir de executare
(Ob n cazul nostru) nu este ocupat i deci poate invoca n continuare metode care sunt
executate concurent cu aciunile firului.
Dac n loc de Ob.start() am fi folosit Ob.run(), programul ar rula la
infinit.
Exemplul 3. Relum Exemplul 2, utiliznd interfaa Runnable n loc de clasa
Thread.
import java.util.*;
class Tip implements Runnable {
int k; boolean b = true;
public void run() {
while (b) System.out.print(" " + k++);
System.out.println("Fir");
}
public void terminare() { b = false; }
}
class P2 {
public static void main(String[] arg) {
Tip Ob = new Tip();
Thread T = new Thread(Ob);
T.start();
Scanner sc = new Scanner(System.in);
while (sc.next().charAt(0) != 'q');
Ob.terminare(); System.out.println("main");
}
}
5
ncercarea de mai sus nu este corect: n final n poate avea o valoare diferit de
cea ateptat; mai mult, la executri diferite ale programului ce transpune aceast
ncercare de rezolvare, se pot obine rezultate diferite. Explicaia const n primul rnd
n faptul c instruciunea n n+1 (asupra resursei/variabilei comune n) nu este
nedivizibil (nu este o aciune "atomic"), iar n al doilea rnd n modul de executare al
programelor concurente. ntr-adevr, instruciunea n n+1 este n realitate o
secven format din trei instruciuni n cod main:
LOAD n,r
INC r
STORE r,n
n
0
r1
r2
0
1
0
1
1
1
2
2
1
void incr() {
r = n; delay(); r++; delay(); n = r; delay();
}
"+i);
6
class AtribMult0 {
public static void main(String[] s) {
Tip[] T = new Tip[5];
for (int i=0; i<5; i++) T[i] = new Tip(i);
for (int i=0; i<5; i++) T[i].start();
try { for (int i=4; i>=0; i--) T[i].join(); }
catch (InterruptedException e) { }
System.out.println("\nn = " + C.n);
}
}
void delay() {
try { Thread.sleep( (int) (100 * Math.random()) ); }
catch(InterruptedException e) { }
}
synchronized void incr() {
r = n; delay(); r++; delay(); n = r; delay();
}
"+i);
7
class AtribMult {
public static void main(String[] s) {
Tip.Ob = new C();
Tip[] T = new Tip[5];
for (int i=0; i<5; i++) T[i] = new Tip(i);
for (int i=0; i<5; i++) T[i].start();
try { for (int i=4; i>=0; i--) T[i].join(); }
catch (InterruptedException e) { }
System.out.println("\nn = " + C.n);
}
}
import java.util.*;
public class Sumator {
public int[] a;
private int suma=0, indice=0;
private int nt=0; // cati termeni au fost adunati la suma
private int n=0, nr_fire=10;
public Sumator() {
Scanner sc = new Scanner(System.in);
System.out.print("n = "); n = sc.nextInt();
a = new int[n];
for (int i=0; i<n; i++) a[i] = i;
for (int i=0; i<10; i++)
new Fir(this,i).start();
}
public synchronized int indiceNou() {
8
if (indice < n) return indice++;
else return -1;
}
public synchronized void adunap(int sumap) {
suma += sumap;
if (++nt == nr_fire)
System.out.println("Suma totala este " + suma);
}
public static void main(String args[]) {
new Sumator();
}
}
class Fir extends Thread {
// nr = nr. de ordine al firului;
// sumap = suma partiala calculata de firul curent
int sumap = 0, nr;
Sumator s;
public Fir(Sumator s, int nr){
this.s = s; this.nr = nr;
}
public void run() {
int indice = s.indiceNou();
while(indice != -1) {
try { Thread.sleep(2); }
catch(InterruptedException ie) { }
sumap += s.a[indice];
indice = s.indiceNou();
}
System.out.println("Suma partiala a firului "
+ nr + " este " + sumap);
s.adunap(sumap);
}
}