• Aucun résultat trouvé

Programmation Concurrente en JAV A

N/A
N/A
Protected

Academic year: 2022

Partager "Programmation Concurrente en JAV A"

Copied!
7
0
0

Texte intégral

(1)

Programmation Concurrente en J AV A

T M

Document en cours d’´elaboration issu de plusieurs versions ´elabor´ees principalement par J-P. Rigault, puis par M.

Cosnard, J-F. Lalande, et F. Peix, et enfin aujourd’hui par I. Sau et M. Syska.

TP2 : Exclusion mutuelle et s´emaphores en Java

14 F´evrier 2007

1 Gestion des entr´ees/sorties d’un parking

Dans cet exercise on souhaite compter les entr´ees et sorties des v´ehicules dans un parking pour afficher le nombre de places occup´ees. Ici, pour simplifier on ne comptera que les entr´ees. Le fonctionnement du parking est simple:

• Il y a2portes d’entr´ee au parking (P dans le cas g´en´eral).

• Le parking a capacit´e2N (P ·N dans le cas g´en´eral).

• N voitures entrent par chaque porte du parking.

Le but de cet exercice est de compter les voitures qu’il y a dans le parking en utilisant une seule vari- able partag´ee. On va utiliser l’algorithme de Peterson pour garantir l’exclusion mutuelle entre les threads.

Id´ee de l’algorithme de Peterson (avec 2 threads):

/ / Chaque t h r e a d a 3 ” f l a g s ” e n t i e r s ( p a r t a g ´e s ) e t s o n i d e n t i f i c a t e u r : / / m o n f l a g , f l a g a u t r e t h r e a d , d e r n i e r , m o n i d

p r i v a t e v o i d e n t r e r s e c t i o n c r i t i q u e ( . . . ){ m o n f l a g <− 1

d e r n i e r <− m o n i d

w h i l e ( f l a g a u t r e t h r e a d ==1 && d e r n i e r == m o n i d ) {}

}

p r i v a t e v o i d s o r t i r s e c t i o n c r i t i q u e ( . . . ){

(2)

Corps du programme:

i m p o r t j a v a . u t i l . c o n c u r r e n t . a t o m i c . * ;

/ / On d e f i n i t une c l a s s e p o u r p o u v o i r p a r t a g e r l e c o m p t e u r : p u b l i c c l a s s m i n t e g e r {

p r i v a t e i n t v a l u e ; p u b l i c m i n t e g e r ( ){

v a l u e = 0 ; }

p u b l i c v o i d s e t v a l u e ( i n t n e w v a l u e ){

t h i s . v a l u e = n e w v a l u e ; }

p u b l i c i n t g e t v a l u e ( ){ r e t u r n t h i s . v a l u e ; }

}

p u b l i c c l a s s P o r t e e x t e n d s T h r e a d { . .

}

p u b l i c c l a s s P a r k i n g P e t e r s o n {

p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { . . .

} }

(3)

2 Le coiffeur dormeur

Il s’agit encore d’un de ces probl`emes de synchronisation mis sous une forme ”plaisante”. Mais celui-ci est encore plus s´erieux que le probl`eme classique des philosophes1, car on en trouve une application presque directe dans certains m´ecanismes des syst`emes d’exploitation (comme l’ordonnancement des acc`es disque).

Description du probl`eme:

• Un coiffeur poss`ede un salon avec un si`ege de coiffeur et une salle d’attente comportant un nombre fixeF de fauteuils.

• S’il n’y a pas de client, le coiffeur se repose sur son si`ege de coiffeur.

• Quand un client arrive:

– s’il trouve le coiffeur endormi, il le r´eveille, s’assoit sur le si`ege de coiffeur et attend la fin de sa coupe de cheveux.

– si le coiffeur est occup´e lorsque le client arrive, le client s’assoit et s’endort sur une desCchaises de la salle d’attente.

– si le coiffeur est occup´e lorsque le client arrive et la salle d’attente est pleine, le client repasse plus tard.

• Lorsque le coiffeur a termin´e une coupe de cheveux, il fait sortir son client courant et va r´eveiller un des clients de la salle d’attente.

• Si la salle d’attente est vide, le coiffeur se rendort sur son si`ege jusqu’`a ce qu’un nouveau client arrive.

Le but de de cet exercice est d’associer une thread au coiffeur ainsi qu’`a chaque client et de programmer une s´eance de coiffeur dormeur en Java, et d’utiliser les s´emaphores pour garantir l’exclusion mutuelle parmi les processus.

2.1 Avec des s´emaphores

Pour cet exercice on utilisera les s´emaphores de la JDK 1.5. On ´ecrira une classe pour le coiffeur (Bar- berSemaphore) et une classe pour les clients (CustomerSemaphore). L’id´ee est que la communication se fasse au travers de s´emaphores, bloquant l’ex´ecution des threads quand cela est n´ecessaire.

(4)

i m p o r t j a v a . u t i l . c o n c u r r e n t . Sem a phore ;

/ / ========================================================================

/ / B a r b e r S e m a p h o r e i n J a v a

/ / −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

/ / Usage :

/ / j a v a c B a r b e r S e m a p h o r e . j a v a

/ / j a v a B a r b e r S e m a p h o r e n b C h a i r s n b C u s t o m e r s

/ / ========================================================================

/ / S emaph ore s e m a p h o r e = new Sem aphor e ( c a p a c i t e ) ;

/ / Method P on Semaphore ” s e m a p h o r e ” : s e m a p h o r e . a c q u i r e ( ) ; / / Method V on Semaphore ” s e m a p h o r e ” : s e m a p h o r e . r e l e a s e ( ) ; / / S i m u l a t e b a r b e r b e h a v i o r s w i t h Sem apho re :

c l a s s B a r b e r S e m a p h o r e e x t e n d s T h r e a d { . . .

}

c l a s s C u s t o m e r S e m a p h o r e e x t e n d s T h r e a d { . . .

}

p u b l i c c l a s s S e a n c e {

p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { . . .

} }

(5)

ANNEXE: Solution de la partie 4 du TP1

p a c k a g e TD1 ;

//========================================================================

/ / Showing t h a t s y n c h r o n i z a t i o n b e t w e e n t h r e a d s i s n e e d e d

//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

/ / Usage :

/ / j a v a c N o n S y n c h r o T h r e a d s . j a v a

/ / j a v a N o n S y n c h r o T h r e a d s n l o o p n s i z e | g r e p BAD

//========================================================================

/ / W r i t e t h e same number i n a g i v e n a r r a y : c l a s s M y T h r e a d N o n S y n c h r o W r i t e e x t e n d s T h r e a d {

i n t i d ; / / t h i s w r i t e r i d

i n t n l o o p ; / / number o f i t e r a t i o n s i n t [ ] t a b ; / / a s h a r e d a r r a y

p u b l i c M y T h r e a d N o n S y n c h r o W r i t e ( i n t i d , i n t n l o o p , i n t [ ] t a b , S t r i n g name ) { s u p e r ( name ) ;

t h i s . i d = i d ;

t h i s . n l o o p = n l o o p ; t h i s . t a b = t a b ; }

p u b l i c v o i d r u n ( ) { t r y {

f o r ( i n t i = 0 ; i < n l o o p ; i ++) {

f o r ( i n t j = 0 ; j < t a b . l e n g t h ; j ++) { t a b [ j ] = i d ;

s l e e p ( 5 0 ) ; / / y i e l d ( ) ; }

}

} c a t c h ( E x c e p t i o n e ) {

S y s t e m . e r r . p r i n t l n ( ” E x c e p t i o n i n M y T h r e a d N o n S y n c h r o W r i t e ” + e ) ; }

(6)

/ / V e r i f y t h a t a l l n u m b e r s o f a g i v e n a r r a y a r e e q u a l :

c l a s s MyThreadNonSynchroRead e x t e n d s T h r e a d { i n t n l o o p ; / / number o f i t e r a t i o n s

i n t [ ] t a b ; / / a s h a r e d a r r a y

p u b l i c MyThreadNonSynchroRead ( i n t n l o o p , i n t [ ] t a b , S t r i n g name ) { s u p e r ( name ) ;

t h i s . n l o o p = n l o o p ; t h i s . t a b = t a b ; }

p u b l i c v o i d r u n ( ) { t r y {

f o r ( i n t i = 0 ; i < n l o o p ; i ++) { i n t sum = 0 ;

f o r ( i n t j = 0 ; j < t a b . l e n g t h ; j ++) { sum += t a b [ j ] ;

}

i f ( sum % t a b . l e n g t h ! = 0 ) {

S y s t e m . o u t . p r i n t l n ( ”BAD a t i = ” + i + ” sum = ” + sum ) ; }

}

} c a t c h ( E x c e p t i o n e ) {

S y s t e m . e r r . p r i n t l n ( ” E x c e p t i o n i n MyThreadNonSynchroRead ” + e ) ; }

S y s t e m . o u t . p r i n t l n ( ” End o f ” + t h i s . getName ( ) ) ; r e t u r n ;

} }

(7)

p u b l i c c l a s s N o n S y n c h r o T h r e a d s {

p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { t r y {

/ / r e a d command−l i n e a r g u m e n t s i f ( a r g s . l e n g t h ! = 2 ) {

S y s t e m . e r r . p r i n t l n ( ” u s a g e : N o n S y n c h r o T h r e a d s n l o o p n s i z e ” ) ; S y s t e m . e x i t ( 1 ) ;

}

i n t n l o o p = I n t e g e r . p a r s e I n t ( a r g s [ 0 ] ) ; i n t n s i z e = I n t e g e r . p a r s e I n t ( a r g s [ 1 ] ) ;

S y s t e m . e r r . p r i n t l n ( ” S t a r t i n g N o n S y n c h r o T h r e a d s f o r n l o o p = ” + n l o o p + ” and n s i z e = ” + n s i z e ) ;

i n t [ ] t a b = new i n t [ n s i z e ] ;

/ / t h r e a d c r e a t i o n

T h r e a d t h 1 = new M y T h r e a d N o n S y n c h r o W r i t e ( 0 , n l o o p , t a b , ” W r i t e r 0 ” ) ; T h r e a d t h 2 = new M y T h r e a d N o n S y n c h r o W r i t e ( 1 , n l o o p , t a b , ” W r i t e r 1 ” ) ; T h r e a d t h 3 = new MyThreadNonSynchroRead ( n l o o p , t a b , ” R e a d e r 0 ” ) ;

/ / s t a r t i n g t h r e a d s t h 1 . s t a r t ( ) ;

t h 2 . s t a r t ( ) ; t h 3 . s t a r t ( ) ;

} c a t c h ( E x c e p t i o n e ) { / / r e p o r t any e x c e p t i o n s

S y s t e m . e r r . p r i n t l n ( ” E x c e p t i o n i n N o n S y n c h r o T h r e a d s . main ” + e ) ; }

} }

Références

Documents relatifs

– L'objet représentant la thread qui est actuellement en train d'exécuter du code peut être obtenu par la méthode.

– L'objet représentant la thread qui est actuellement en train d'exécuter du code peut être obtenu par la méthode.

Avec comme argument un contrôleur de processus léger, héritant de la classe Thread, dont la méthode run() de la cible spécifie du code. Lorsqu'elle s'arrête, la JVM appelle

 Le chargeur met aussi un temps aléatoire entre MIN_CH et MAX_CH secondes pour charger un paquet dans le navire, où MIN_CH et MAX_CH sont paramétrables..  On

public abstract class Handler&lt;V&gt;{ // héritée par tout maillon protected Handler&lt;V&gt; successor = null;. public Handler(){ this.successor

public static void main(String [] args) throws IOException{. ServerSocket serveur =

public static void main(String [] args) throws IOException{. ServerSocket serveur =

La méthode sleep de la classe Thread permet de suspendre un thread (le place dans l'état sleeping).. L'utilisation de la méthode sleep implique de traiter