Correction de TD6: Gestion des processus, Les Sémaphores, et Serveurs multithreadés

Page 1 sur 6Lecteur de document UniversityLib

Correction de TD6: Gestion des processus, Les Sémaphores, et Serveurs multithreadés

Concurrent Programming · course

Faculté des Sciences de Bizerte SI3 AU:2015-2016

Correction de TD6

Gestion des processus

Exercice 1 : Compteurs

1.

public class Compteur extends Thread

{

public void run()

{

//un thread permettant de compter de 1 à 10

for(int i=1; i<=10; i++)

{

try

{

System.out.println(this.getName()+i);

//pause de 1000 millisecondes

Thread.sleep ((int)(java.lang.Math.random()*1000));

}

//L'utilisation de la méthode sleep implique de traiter

//l'exception InterruptedException.

catch (InterruptedException e)

{

e.printStackTrace();

}

}

}

public static void main(String[] args)

{

new Compteur().start();

}}

2.

class Compteur2 implements Runnable {

static final int N =10;

int valeur ;

String name ;

//Constructeur

Compteur2( String n )

{

name = n ;

}

// redéfinir la méthode run() de l'interface Runnable

public void run ( )

{

try

{

for ( int i =1; i<=N; i++)

{

Thread.sleep(10); ;

}

System.out.println (name ) ;

}

catch ( Exception e )

{

return ;

}

}

1 Wiem BEN ROMDHANE

Faculté des Sciences de Bizerte SI3 AU:2015-2016

public static void main ( String [ ] args )

{

Runnable compte1 = new Compteur2 ("Assma");

Runnable compte2 = new Compteur2 ("Alaa");

Runnable compte3 = new Compteur2 ("Youssef");

Runnable compte4 = new Compteur2 ("Ahmed");

//lancement de thread se fait par la méthode start()

// 4 threads différents

new Thread(compte1).start();

new Thread(compte2).start();

new Thread(compte3).start();

new Thread(compte4).start();

}

}

Les threads ne peuvent pas s’exécuter de manière séquentielle, ce qui signifie que le thread 1

peut ne pas être le premier thread où son nom sera écrit dans System.out. C’est parce que les

threads sont en principe s’exécutent en parallèle et non pas de manière séquentielle.

la JVM et / ou les systèmes d'exploitation déterminent l'ordre dans lequel les threads sont

exécutés. Cet ordre n'a pas besoin d'être le même ordre dans lequel ils ont été lancés.

3.

public class Compteur3 implements Runnable {

static final int N =10;

class Node

{

public String name ;

Publicité

public Node next ;

public Node ( String n)

{

this . name=n ;

this . next=null ;

}

static Node knownNames ;

}

boolean alreadyKnown (String name)

{

if (knownNames ==null )

{

knownNames= new Node (name);

return false ;

}

Node tmp=knownNames ;

while ( tmp!= null )

{

if ( tmp.name.equals(name))

return true ;

tmp=tmp.next ;

}

tmp=knownNames ;

while (tmp.next!=null)

tmp=tmp.next ;

tmp.next=new Node(name);

return false ;

}

int valeur ;

String name ;

Compteur3 (int val,String n) throws Exception

{

if (alreadyKnown(n)) throw new Exception() ;

2 Wiem BEN ROMDHANE

Faculté des Sciences de Bizerte SI3 AU:2015-2016

valeur = val ;

name = n ;

}

public void run ( )

{

try

{

for ( int i =1; i<=N; i++)

{

Thread.sleep((int)(java.lang.Math.random()*100));

}

System . out . println (name ) ;

}

catch ( Exception e )

{

return ;

}

}

public static void main ( String [ ] args ) throws Exception

{

Runnable compte1 = new Compteur3 (10 , "Ahmed" ) ;

Runnable compte2 = new Compteur3 (10 , "Assma" ) ;

Runnable compte3 = new Compteur3 (10 , "Ahmed" ) ;

Runnable compte4 = new Compteur3 (10 , "Youssef" ) ;

//Exception in thread "main" java.lang.Exception

//at Exercice1.Compteur3.<init>(Compteur3.java:41)

//at Exercice1.Compteur3.main(Compteur3.java:63)

new Thread ( compte1 ) . start ( ) ;

new Thread ( compte2 ) . start ( ) ;

new Thread ( compte3 ) . start ( ) ;

new Thread ( compte4 ) . start ( ) ;

} }

4.

public class CompteurX extends Thread {

private String nom;

private int max;

private static int ordre = 1;

public CompteurX(String nom, int max) {

this.nom = nom;

this.max = max;

}

public void run() {

for (int i = 1; i <= max; i++) {

try {

sleep((int)(Math.random() * 100));

}

catch(InterruptedException e) {

System.err.println(nom + " a ete interrompu.");

Publicité

}

System.out.println(nom + " : " + i);

}

System.out.println("* " + nom + " a termine en position " + ordre++);

}

public static void main(String[] args) {

Runnable compte1 = new CompteurX ("Ahmed",10);

Runnable compte2 = new CompteurX ("Assma",10);

3 Wiem BEN ROMDHANE

Faculté des Sciences de Bizerte SI3 AU:2015-2016

Runnable compte3 = new CompteurX ("Alaa",10);

Runnable compte4 = new CompteurX ("Youssef",10);

new Thread ( compte1 ).start();

new Thread ( compte2 ).start();

new Thread ( compte3 ).start();

new Thread ( compte4 ).start();

}

} // CompteurX

Exercice 2 : Les Sémaphores

La sémaphore est une technique qui permet la gestion de ressources avec le mécanisme de

vérouillage et déverouillage. Il permet de préciser le nombre de Threads qui peuvent accédér à

une ressource à un moment donné.

Un sémaphore correspond à un compteur (permits) qui ne peut être accédé que par deux

opérations atomiques: acquire (P) et release (V). L'opération acquire ou

"verrouille" décrémente le compteur permits alors que l'opération release ou

"déverrouille" l'incrémente.

Un sémaphore binaire est un objet sur lequel on peut appliquer ces deux méthodes.

1.

public class BoundedSemaphore

{

private int signals = 0 ;

private int bound = 0 ;

public BoundedSemaphore ( int upperBound ) {

bound = upperBound ;

}

public synchronized void acquire ( ) throws InterruptedException {

while ( signals == bound )

wait ( ) ;

signals++;

notify ( ) ;

}

public synchronized void release ( ) throws InterruptedException {

while ( signals == 0)

wait ( ) ;

signals--;

}

}

2. Cela permet de réaliser l'exclusion mutuelle, donc l'accès par des processus à des sections

critiques

import java.util.concurrent.Semaphore;

public class essaiPV extends Thread {

static int x = 3;

Semaphore u;

public essaiPV(Semaphore s) {

u = s;

}

4 Wiem BEN ROMDHANE

Faculté des Sciences de Bizerte SI3 AU:2015-2016

public void run() {

int y;

// u.P();

try {

Thread.currentThread().sleep(100);

y = x;

Thread.currentThread().sleep(100);

y = y+1;

Thread.currentThread().sleep(100);

x = y;

Thread.currentThread().sleep(100);

} catch (InterruptedException e) {};

System.out.println(Thread.currentThread().

getName()+": x="+x);

// u.V();

}

public static void main(String[] args) {

Semaphore X = new Semaphore(1);

new essaiPV(X).start();

new essaiPV(X).start();

}

}

Dans ce cas, les deux processus s'exécutent de façon à peu près synchrone, lisent tous les deux

x et trouvent la valeur 3, incrémentent en même temps leur copie locale, pour écrire la valeur

4 dans x.

Publicité

Exercice 3 : Serveurs multithreadés

1. Le multithreading permet d’améliorer la performance globale et la transparence de

plusieurs applications. Par exemple, un serveur en mode multithreading continue à recevoir

les connexions même s’il est encore en train de traiter d’autres requêtes.

import java.io.IOException ;

import java.net.ServerSocket ;

import java.net.Socket ;

public final class TcpServer extends Thread {

private ServerSocket serverSocket;

private int portNumber = 4000;

public TcpServer () throws IOException {

setName ( "TcpServer" ) ;

// create a ServerSocket instance and bind it to the

// specified port number

serverSocket = new ServerSocket ( portNumber ) ;

}

public void run () {

try{

while (!isInterrupted ())

{

// accept a new connection

Socket socket = serverSocket.accept() ;

// create a new thread to handle communication with

// the remote client

new ConnectionHandler(socket).start() ;

}

5 Wiem BEN ROMDHANE

Faculté des Sciences de Bizerte SI3 AU:2015-2016

}

catch( IOException e ) {

e.printStackTrace () ;

}

}

public static void main ( String [] args ) {

try{

TcpServer tcpServer = new TcpServer () ;

tcpServer.start() ;

}

catch( IOException e ) {

e.printStackTrace() ;

}

}

}

import java.io.BufferedReader ;

import java.io.IOException ;

import java.io.InputStreamReader ;

import java.io.PrintWriter ;

import java.net.Socket ;

import java.util.Date ;

public final class ConnectionHandler extends Thread {

private Socket socket ;

public ConnectionHandler ( Socket socket ) {

setName ( "ConnectionHandler" ) ;

this.socket = socket ;

}

public void run () {

BufferedReader in = null ;

PrintWriter out = null ;

String request ;

try{

// Get the input and output streams

in = new BufferedReader

(new InputStreamReader (socket.getInputStream ())) ;

out = new PrintWriter (socket.getOutputStream () , true ) ;

while ( ( request = in.readLine ()) != null ) {

if ( request.equals ( "GET TIME"))

out.println (new Date().toString ()) ;

// Deliver the JRE version if the clients ends GET JAVA VERSION

else if ( request.equals ( "GET JAVA VERSION"))

out.println ( System.getProperty ( " java.version")) ;

// Exit the loop if the clients ends CLOSE

else if ( request.equals ( "CLOSE"))

break ;

}

}

catch( IOException e ) {

e.printStackTrace () ;

}} }

6 Wiem BEN ROMDHANE