vineri, 12 februarie 2010

Java: Ceas digital (folosite Thread, notify,wait)

//Clasa Secunde


public class Secunde extends Thread {
private Tic copieTic;
private int secunde;
public Secunde(Tic tic)
{
copieTic=tic;
}
public void run()
{
//daca nu folosim o bucla infinita dupa 1 secunda se termina ciclul si threadul "moare"
while(true)
{
try{
Thread.sleep(1000);
}
catch(Exception e)
{
System.out.println("Eroare in Secunde");
}
System.out.println("Sec: "+secunde);
if(secunde==59){
secunde=0;
copieTic.increment();
}
else
secunde++;
//se face o incrementare la fiecare 1000ms,
//daca s-a ajuns la 59, se revine in 0 si se semnalizeaza in Tic
}
}
}


//Clasa Minute


public class Minute extends Thread{
private Tic copieTic;
private int minute;
public Minute(Tic tic){
copieTic=tic;
}
public void run(){
while(true){
copieTic.astept();
minute++;
System.out.print("Minute: "+minute+" ");
if(minute==59)
minute=0;//in mod normal s-ar incrementa orele...
}
}
}


//Clasa Tic, realizeaza comunicarea intre fire


public class Tic {
private boolean eveniment;
public synchronized void astept(){
while(!eveniment)
{
try{
wait();
}
catch(Exception ex){
System.out.println("Eroare in astept()");
}
}
eveniment=false;
}
public synchronized void increment(){
System.out.println("In increment");
eveniment=true;
notify();
}
}


//Clasa Main, principala


public class Main {
public static void main(String[] args){
Tic tic=new Tic();
Secunde sec=new Secunde(tic);
Minute min=new Minute(tic);
sec.start();
min.start();
}
}



/**Scurte precizari
* Folosirea lui wait() are ca rol de a trece obiectul apelant in starea Blocked
* Folosirea lui notify() are efectul invers
* Metodele de tip synchronized produc un "lacat" per clasa si nu per obiect
* Variabila booleana eveniment se foloseste pentru verificare(se poate renunta la folosirea ei)
* Se poate modifica ai sa nu mai folosim wait() si notify prin testarea directa in Minute daca var booleana eveniment a devenit true
*/
Functionare: Se pornesc cele 2 fire, "lacatul" de pe clasa Tic este folosit de catre Minute(prin metodaastept()), care are ca efect blocarea lui Minute. Intre timp, threadul Secunde continua incrementarea secundelor. Cat timp nu s-a ajuns la 59, nu se apeleaza metode din Tic, deci implicit nu folosim lacatul. Cand se ajunge la 59 secunde, prin metoda increment() din Tic se deblocheaza threadul Minute. El va apela astept() se blocheaza, si ciclul se reia...

Vezi Head First in Java, in special paginile 490 - 516 si Unraveling threads sau Sincronizarea threadurilor(exemplul producator-consumator)

Niciun comentariu:

Trimiteți un comentariu