Exemple simple de processus legers

Dans cet exemple on trouve deux classes :

Applet :

La gestion des processus legers en meme temps qu'une applet n'est pas triviale car une applet semble elle-meme etre composee de plusieurs processus (qui sont caches). On doit garantir que l'applet aura regulierement la main pour gerer l'affichage, les evenements, etc... Ici, par exemple, le debut du traitement des processus a ete retarde par un sleep pour permettre d'attendre les evements souris sans rester bloque dans un des processus (qui ne rendrait donc pas la main).

Programme :

import java.applet.* ;

import java.awt.Graphics ;

import java.awt.Event ;

public class leger1 extends Applet

{

    final int NB_PROC=5 ;

    protected Mon_processus[] p ;

    protected int combien, ligne ;

    protected StringBuffer message ;

    protected Graphics gc ;

    protected boolean deja_lance ;

    public void init()

    {

      int i ;

      // declare le tableau de processus

      p = new Mon_processus[NB_PROC] ;

      for (i=0 ; i<NB_PROC ; i++) // alloue chaque processus

        p[i] = new Mon_processus(this, "P"+i) ;

      message = new StringBuffer() ;

      gc = getGraphics() ;

    }

    public void start()

    {

      int i ;

      // les processus doivent etre lances depuis la methode start de l'applet

      for (i=0 ; i<NB_PROC ; i++)

        p[i].start() ;

      combien = 0 ; ligne = 0 ; deja_lance = false ;

      message.append("Les " + NB_PROC + " processus ont ete initialises.") ;

      message.append(" Cliquez sur la souris pour les lancer.") ;

      paint(gc) ;

    }

    public void stop()

    {

      int i ;

      message = new StringBuffer("") ;

      for (i=0 ; i<NB_PROC ; i++) p[i].stop() ;

    }

    public void destroy()

    {

      int i ;

      for (i=0 ; i<NB_PROC ; i++) { p[i] = null ; }

    }

    public void paint(Graphics g)

    { g.drawString(message.toString(), 5, 10+10*ligne) ; ligne ++ ; }

    public boolean mouseDown(Event evt, int x, int y)

    {

      int i ;

      message = new StringBuffer("clic !") ;

      paint(gc) ; // update(gc) effacerait en plus l'ecran

      if (!deja_lance)

      {

        for (i=0 ; i<NB_PROC ; i++) p[i].dit_ok() ; // on debloque chaque processus

        deja_lance=true ;

      }

      return(true) ;

    }

    public void ecriture(StringBuffer msg)

    { message = new StringBuffer(msg.toString()+ " ecrit.") ; paint(gc) ; }

    public void proc_fini()

    {

      combien ++ ;

      if (combien==NB_PROC)

      { message = new StringBuffer("Les " + NB_PROC + " processus ont fini.") ; paint(gc) ; stop() ; }

    }

}

class Mon_processus extends Thread

{

    private StringBuffer mon_nom ;

    leger1 mon_pere ; // on a besoin d'une reference de l'applet pour ecrire

    int message ; // nombre de messages envoyes

    boolean ok ; // va servir a bloquer le processus avant de lancer le traitement

    Mon_processus(leger1 pere, String nom)

    { super() ; ok = false ; mon_nom = new StringBuffer(nom) ; mon_pere = pere ; }

    // run est le corps du processus

    public void run()

    {

      message = 0 ;

      while (! ok) // attente bloquante qui laisse la main a l'applet

      {

        try { sleep((int)(Math.random()*1000.0)) ; }

        catch (InterruptedException e) {} // le sleep permet de redonner la main aux autre processus

      }

      while (message<mon_pere.NB_PROC)

      {

        try { sleep((int)(Math.random()*1000.0)) ; }

        catch (InterruptedException e) {}

        mon_pere.ecriture(mon_nom) ;

        message++ ;

      }

      jai_fini() ;

    }

    public void dit_ok()

    { ok = true ; }

    protected void jai_fini()

    { mon_pere.proc_fini() ; }

}


Ph. RIS 1997