Skip Navigation Links
Accueil
Java Standard EditionExpand Java Standard Edition
Java EE 5Expand Java EE 5
Visual Basic .Net 2005Expand Visual Basic .Net 2005
Visual C++ .Net 2005Expand Visual C++ .Net 2005
Visual C# .Net 2005Expand Visual C# .Net 2005
Cours ASP .Net 2.0Expand Cours ASP .Net 2.0
PostgresqlExpand Postgresql
LinuxExpand Linux
Visual Studio 2008Expand Visual Studio 2008
ASP 3.0 ClassiqueExpand ASP 3.0 Classique
Cours Javascript - DOM - DHTMLExpand Cours Javascript - DOM - DHTML
Cours AjaxExpand Cours Ajax
VBAExpand VBA
AssembleurExpand Assembleur
PerlExpand Perl
MembresExpand Membres
L'auteur du site
Nouveautés sur le site
Contacts
Plan du site
Accueil > Java Standard Edition > Les threads: généralités
____________________________________________________________________________________________________
Connexion

JSE - le langage - les threads(1): généralités

Sommaire :

I) Introduction
II) Différences en thread et processus(ou process)
III) Implémentation des threads
IV) La classe Thread(java.lang)
   IV.1) Création d'une classe héritant de Thread
   IV.2) Démarrage du thread
   IV.3) Problème d'héritage multiple
      IV.3.A) L'interface Runnable (java.lang)
      IV.3.B) Construire un thread avec le constructeur runnable
      IV.3.C) Utilisation avec Runnable
      IV.3.D) Conclusion sur Runnable
(Suite dans une autre page)
V) Les méthodes de la classe Thread
VI) Le thread de la méthode main
VII) L'erreur ThreadDeath(java.lang) levée par la méthode deprecated stop()
VIII) La synchronisation des threads
IX) Code source complet de l'exemple
   IX.1) classe Main (package main)
   IX.2) Classe DemonCompte (package threads)
   IX.3) Classe threadVoiture (package threads)
   IX.4) Classe Voiture (package vehicules)
   IX.5) Classe VoitureMT (package vehicules)
X) Téléchargement de l'exemple

I) Introduction

Le langage java est multi-thread. Cela signifie que plusieurs programmes peuvent s'exécuter au même moment, en parallèle. Cela comporte des avantages, que nous ne détaillerons pas ici.

II) Différences en thread et processus(ou process)

Un processus est une application. Il possède un ou plusieurs threads.
Les applications peuvent s'exécuter en parallèle, ce qui est traité par le système d'exploitation. Chacune d'elle possède ses ressources propres, notamment la mémoire, mais aussi des ressources comme l'écran, la souris etc...

Par contre, tous les threads d'un processus utilisent les ressources de ce processus. Il y a donc partage des ressources de ce process par l'ensemble de ses threads.

III) Implémentation des threads

La JVM utilise directement les threads natifs du système d'exploitation, pour des problèmes de performances.

IV) La classe Thread(java.lang)

C'est la classe Thread qui possède toutes les fonctions "native", qui ne sont pas implémentées en java, et qui utilisent directement l'interface native du système d'exploitation.

Thread représente un thread ne faisant rien, car sa méthode run() ne fait rien.
En réalité, nous verrons plus tard que run() ne fait rien, si on a construit notre thread avec un constructeur prenant une string en argument(ce que nous fairons pour l'instant).
Il est donc indispensable de créer une classe héritant de Thread, et de redéfinir la méthode run()(une autre solution existe, avec les Runnable, que nous verrons après).
Vous l'avez compris, la méthode run() est la méthode qui doit contenir le code exécuté parallèlement.

IV.1) Création d'une classe héritant de Thread

On crée notre classe de Thread, comme dans le projet d'exemple:

IV.2) Démarrage du thread

Regardons maintenant le main: On crée d'abord un objet threadVoiture, dont le nom est thVoitJean.
Pour démarrer ce thread, on appelle sa méthode start().

Ici, on crée deux threads différents, et pour cela il est nécessaire de créer un objet Thread par thread.

L'exemple ici simule le démarrage de deux voitures, qui vont à deux vitesses différentes: l'une à 100 m/s, et l'autre à 200 m/s.

Le résultat de l'exécution est le suivant:

Début thread thVoitJean
Début thread thVoitPierre
thVoitPierre:200 mètres parcourus
thVoitJean:100 mètres parcourus
thVoitPierre:400 mètres parcourus
thVoitJean:200 mètres parcourus
thVoitPierre:600 mètres parcourus
thVoitJean:300 mètres parcourus
thVoitPierre:800 mètres parcourus
thVoitJean:400 mètres parcourus
thVoitPierre:1000 mètres parcourus
thVoitJean:500 mètres parcourus
thVoitPierre:1200 mètres parcourus
thVoitJean:600 mètres parcourus
thVoitJean:700 mètres parcourus
thVoitPierre:1400 mètres parcourus
thVoitPierre:1600 mètres parcourus
thVoitJean:800 mètres parcourus
thVoitPierre:1800 mètres parcourus
thVoitJean:900 mètres parcourus
thVoitJean:1000 mètres parcourus
thVoitPierre:2000 mètres parcourus

IV.3) Problème d'héritage multiple

On s'aperçoit que la méthode précédente ne nous permet pas d'avoir notre classe de thread qui hérite déjà d'une autre classe.

Par exemple, si on veut faire hériter notre classe threadVoiture, de la classe Voiture. On ne pourrait pas, car threadVoiture hérite déjà de la classe Thread.

De plus, on aurait voulu plutôt l'appeler VoitureMT(voiture multi-thread), car l'objet obtenu représenterait d'avantage une voiture, plutôt qu'un thread. Du point de vue du raisonnement, on voit bien un problème de l'héritage multiple: cela complique le raisonnement, car on a un objet qui représente deux réalités( ici une voiture et un thread).

Les interfaces permettent de résoudre le problème. Car l'objet qui hérite d'une classe, par exemple qui hérite de Voiture, représente toujours une voiture. Et, de plus, il possède des capacités particulières, du fait des interfaces implémentées(ici la capacité d'être démarrable). Mais, du point du vue du raisonnement, il représente toujours une voiture.

IV.3.A) L'interface Runnable (java.lang)

Nous nous apercevons que l'interface Runnable comporte une seule méthode: la méthode void run().

Remarque: le abstract de run() est redondant, c'est pour garder la compatibilité avec les vieilles versions. ("For compatibility with older versions of the Java platform, it is permitted but discouraged, as a matter of style, to redundantly specify the abstract modifier for methods declared in interfaces.", site java.sun.com, chapitre sur les interfaces).

Il suffit de faire implémenter cette interface Runnable par notre classe voitureMT.

Notre objet voitureMT devient alors démarrable, on est certain qu'il possède une méthode public void run().

IV.3.B) Construire un thread avec le constructeur runnable

Un des constructeur de la classe Thread, prend un objet Runnable en paramètre.
Il faut l'utiliser, en lui passant notre objet Runnable. En fait, le constructeur va mettre l'objet Runnable dans son attribut privé appelé target. Et la méthode run() de Thread, va juste faire target.run() :

IV.3.C) Utilisation avec Runnable

Prenons l'exemple du projet.
On a deux classes, une mono-thread, et une multi-thread.

Chaque classe représente une voiture.

Regardons la classe Voiture, qui n'est pas multi-thread: C'est classique: on a des attributs de la voiture, et des méthodes, comme la méthode demarrer ou arreter().

Regardons la classe VoitureMT, qui elle est multiThread. VoitureMT hérite de Voiture, et représente toujours une voiture.
Il n'y a pratiquement rien à mettre dans cette classe, juste la méthode run() à créer, qui ne fait qu'appeler la méthode demarrer de la classe mère.

Remarquons que demarrer est toujours accessible, mais n'est pas multi-thread: dans ce cas, on utilise la classe VoitureMT comme si c'était la classe Voiture.

A présent, voici le main: On utilise d'abord la classe Voiture: les deux voitures ne roulent pas en même temps. La deuxième voiture démarre lorsque la première est arrivée.
Puis on utilise la classe VoitureMT. On crée deux voitures de la classe VoitureMT.
Puis on crée deux threads, thJean et thPierre, car nous aurons besoin de deux threads pour exécuter chaque voiture.
Quand on crée chaque thread, on donne au constructeur notre objet VoitureMT, qui est un Runnable.
Il ne reste plus qu'à démarrer chaque thread, avec start().
Les deux voitures démarrent et roulent en même temps.

Voici le résultat de l'exécution pour les voitures multi-threads:

Voitures Multi-threads
La voiture démarre
La voiture démarre
Peugeot 206:200 mètres parcourus
Renault Megane:100 mètres parcourus
Peugeot 206:400 mètres parcourus
Renault Megane:200 mètres parcourus
Peugeot 206:600 mètres parcourus
Renault Megane:300 mètres parcourus
Peugeot 206:800 mètres parcourus
Renault Megane:400 mètres parcourus
Peugeot 206:1000 mètres parcourus
Renault Megane:500 mètres parcourus
Peugeot 206:1200 mètres parcourus
Renault Megane:600 mètres parcourus
Peugeot 206:1400 mètres parcourus
Renault Megane:700 mètres parcourus
Peugeot 206:1600 mètres parcourus
Renault Megane:800 mètres parcourus
Peugeot 206:1800 mètres parcourus
Renault Megane:900 mètres parcourus
Peugeot 206:2000 mètres parcourus
Renault Megane:1000 mètres parcourus

IV.3.D) Conclusion sur Runnable

- On n'a pas eu à réécrire le code de la méthode demarrer(). La programmation multi-thread a été une programmation séquentielle.

- On aurait pu utiliser le même objet Runnable pour les deux threads, ici la même VoitureMT. Dans ce cas, les deux threads auraient partagé les mêmes ressources. Ceci pose des problèmes de modifications concurrentes, et donc nécessite une synchronisation. Nous parlerons de cela par la suite.

V) Les méthodes de la classe Thread
VI) Le thread de la méthode main
VII) L'erreur ThreadDeath(java.lang) levée par la méthode deprecated stop()
VIII) La synchronisation des threads
IX) Code source complet de l'exemple
   IX.1) classe Main (package main)
   IX.2) Classe DemonCompte (package threads)
   IX.3) Classe threadVoiture (package threads)
   IX.4) Classe Voiture (package vehicules)
   IX.5) Classe VoitureMT (package vehicules)
X) Téléchargement de l'exemple

RETOUR HAUT