Fire de executie in Java
1.
permit executarea simultana a mai multor parti din program
constituie o versiune redusa a unui proces
asemanari : ruleaza independent si simultan
deosebiri : la crearea unui nou proces (fork) este realizata o copie exacta
a procesului parinte : cod + date; la crearea unui fir de executie nu este
copiat decât codul procesului parinte; toate firele de executie au deci
acces la aceleasi date, datele procesului original
utilitate : executarea unor operatii în fundal
2. Declararea, instantierea si distrugerea firelor de executie
prin extinderea clasei Thread
prin implementarea interfetei Runnable
2.1 Creearea firelor de executie prin extindrea clasei Thread
public class MyMain {
public static void main(String argsst) {
CntThread cntThread; //declare thread
cntThread = new CntThread(); //create thread
cntThread.start(); //start thread running
try {System.in.read();} //wait for keyboard input
catch(java.io.IOException e){}
cntThread.stop(); //stop thread
}
}
class CntThread extends Thread {
public void run() {
int ix = 0;
while (true) {
System.out.println("running, ix = " + ix++);
//write count to screen
try {Thread.sleep(1000);} //sleep 1 second
catch(InterruptedException e){}
}
}
}
2.2 Creearea firelor de executie prin implementarea interfetei Runnable
import java.applet.* ;
import java.awt.* ;
public class TestThread extends Applet implements Runnable {
Thread mainThread ;
CntThread thread1, thread2;
public void start() {
if (mainThread == null) {
mainThread = new Thread(this);
mainThread.start();
}
}
public void run() {
thread1 = new MyThread(this, 2);
thread1.start();
thread2 = new MyThread(this, 3);
thread2.start();
}
public boolean keyDown( Event evt, int key ) {
thread1.stop();
thread2.stop();
return(true);
}
public void paint( Graphics g) {
g.drawString("Ruleaza 3 fire de executie", 10, 10);
g.drawString("Contor1 :"+thread1.counter, 10, 30);
g.drawString("Contor2 :"+thread2.counter, 10, 50);
}
}
//----------------------------------------------------------------------
class CntThread implements Runnable {
TestThread parent;
boolean loop;
Thread cntThread;
int step;
int counter;
public CntThread(TestThread p, int s) {
parent = p; //salvez instanta parinte
step = s;
}
public void start() {
if (cntThread == null) {
counter = 0;
cntThread = new Thread(this); //creez firul de executie
pentru numarare
cntThread.start(); //lanseaza firul de executie
}
}
public void run() {
loop = true;
while (loop) {
counter += step;
parent.repaint();
try {Thread.sleep(1000);} //pauza de 1 sec
catch (InterruptedException e) {}
}
}
public void stop() {
loop = false;
}
}
2.3 Instantierea unui fir de executie : NEW
mainThread = new Thread(this) ;
myThread = new MyThreadClass();
2.4 Distrugerea unui fir de executie : STOP, DESTROY
myThread = new MyThreadClass();
myThread.start();
myThread.stop();
myThread = null;
Nu este necesara distrugerea explicita a unui fir de executie. Sistemul Java
de colectare a gunoiului se ocupa de acest lucru. El poate fi fortat sa
dezaloce resuresele alocate unui thread prin atribuirea cu null a variabilei
care referea instanta firului de executie
3. Metode pentru firele de executie
init() - apelata la prima lansare a unui fir de executie, locul unde
se scrie codul de initializare
start()- apelata la fiecare lansare, dupa operatiile de initializare
stop()- apelata la terminarea firului de executie, contine codul de
terminare a unui fir de executie
run()- apelata de metoda start, contine corpul firului de executie
3. Denumirea firelor de executie
Thread myThread = new Thread(this.”Nume fir”)
myThread.getName()
myThread.setName()
3. Sincronizarea firelor de executie
Un obiect sau o metoda pot fi accesate de mai multe fire de executie. Nu
exista însa nici o garantie privind firul de executie care va avea acces la un
obiect la un moment dat, ceea ce poate conduce la rezultate imprevizibile.
Pentru a evita acest lucru se foloseste cuvântul cheie synchronized, care
blocheaza un obiect pe perioada executarii unui bloc de cod.
public void incIndex() {
synchronized(index) {
//bloc de cod sincronizat, ob. index este blocat
index++;
System.out.println(“index = “ + index);
}
}
Cuvântul cheie synchronized poate fi folosit si ca modificator al
unei metode, asigurându-se utilizarea ei de catre un singur fir de executie la
un moment dat.
public void synchronized incIndex() {
index++;
System.out.println(“index = “ + index);
}