Fire de executie Java

  • permit executarea simultana a mai multor parti din program
  • constituie o versiune redusa a unui proces
  • asemanari : ruleaza independent sisimultan
  • 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 decat codul procesului parinte; toate firele de executie au deci acces la aceleasidate, datele procesului original
  • utilitate : executarea unor operatii în fundal

Declararea, instantierea sidistrugerea firelor de executie

  • prin extinderea clasei Thread
  • prin implementarea interfetei Runnable

Creearea firelor de executie prin extindrea clasei Thread

public class MyMain
{
    public static void main(String args[])
    {
        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)
            {
                
            }
        }
    }
}

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);
    }

    private class MyThread extends CntThread {
        public MyThread(TestThread testThread, int i) {
            super();
        }
    }
}
//----------------------------------------------------------------------
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 CntThread()
    {
        
    }

    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;
    }
}

Instantierea unui fir de executie : NEW

  • mainThread = new Thread(this) ;

  • myThread = new MyThreadClass();

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

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

Denumirea firelor de executie

  • Thread myThread = new Thread(this.”Nume fir”)

  • myThread.getName()

  • myThread.setName()

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 folose[te cuvantul 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);
        }
 }

Cuvantul cheie synchronized poate fi folosit sica modificator al unei metode, asigurandu-se utilizarea ei de catre un singur fir de executie la un moment dat.

public void synchronized incIndex()
{
        index++;
        System.out.println("index = " + index);
}

Share on


Echipa conspecte.com, crede cu adevărat că studenții care studiază devin următoarea generație de aventurieri și lideri cu gândire globală - și dorim ca cât mai mulți dintre voi să o facă!