IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Gestion de thread, conception


Sujet :

Java

  1. #1
    AkH
    AkH est déconnecté
    Membre du Club
    Homme Profil pro
    Perso
    Inscrit en
    Juillet 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Perso

    Informations forums :
    Inscription : Juillet 2005
    Messages : 58
    Points : 52
    Points
    52
    Par défaut Gestion de thread, conception
    Bonjour,

    Je développe une application client serveur, où le serveur créé un thread pour chaque client.

    Actuellement, lorsqu'un client veux se connecter, il envoie une string de demande de connexion au serveur, le serveur (process principal) vérifie l'identification, instancie un object ObjectInputStream et un objet ObjectOutputStream et si la connection est valide, il créé un thread en passant les deux derniers object plus l'objet socket client.

    Jusque la tout est bon, chaque client obtient son thread et peut communiquer avec lui (envoie et réception de string et d'objet ok).

    Mon problème est le suivant (problème de conception):

    mon client peut demander au serveur de se terminer, ce qui implique de terminer tous les thread fils puis le thread principal.

    Comment faire pour que lorsqu'un thread fils reçoie la commande "terminer", 'demande' au thread père de terminer tous les process fils?

    Dois-je passer une variable (bool ou autre) aux threads fils et lorsqu'un thread fils modifie cette dernière, le thread père est au courant ? (car il y a un système de vérification de changement d'état ?)

  2. #2
    AkH
    AkH est déconnecté
    Membre du Club
    Homme Profil pro
    Perso
    Inscrit en
    Juillet 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Perso

    Informations forums :
    Inscription : Juillet 2005
    Messages : 58
    Points : 52
    Points
    52
    Par défaut
    Après des recherches, j'ai trouvé que mettre tous mes thread dans un ThreadGroup me permettrais avec une interruption de tous les prévenir pour se terminer.

    Mais je n'ai pas bien compris comment inclure les thread dans un groupe
    et comment utiliser cette interruption

  3. #3
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Fondamentalement, oui.

    Tu peux t'aider en utilisant le paquetage java.util.concurrent (c'est même conseillé), mais il n'existe pas de miracle, de petite API toute faite qui va orchestrer le multithreading dans ton appli.

    Donc si tu veux qu'un client arrête proprement ton serveur, à toi d'organiser tes booléens pour que tout se passe au mieux, c'est ça la programmation !

  4. #4
    AkH
    AkH est déconnecté
    Membre du Club
    Homme Profil pro
    Perso
    Inscrit en
    Juillet 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Perso

    Informations forums :
    Inscription : Juillet 2005
    Messages : 58
    Points : 52
    Points
    52
    Par défaut
    Pourrais tu m'aider et me monter comment utiliser soit ThreadGRoup soit la classe concurrent.

    Voici mes sources:

    Pour le client:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
     
    public class Client
    {
    	private static String host = "localhost", username = "unknown";
    	private static int port = 1000;
    	private static String recvLine;
    	private static String sendLine;
    	private static Socket s;
    	private static ObjectInputStream ois;
    	private static ObjectOutputStream oos;
    	private static Student student = null;
    	private static boolean exitValue = false;
     
    	public static void main(String[] args)
    	{
    		// Vérification des arguments
    		...
     
    		boolean validity = askConnection();
     
    		if(validity != false)
    		{
    			communication();
    		}
     
    	}
     
    	private static boolean askConnection()
    	{
    		try
    		{
    			s = new Socket(host, port);
     
    			oos = new ObjectOutputStream(s.getOutputStream());
     
    			sendLine = username;
    			oos.writeObject(sendLine);
     
    			ois = new ObjectInputStream(s.getInputStream());
     
    			recvLine = ois.readObject().toString();
    			if(recvLine.contains("welcome"))
    			{
    				System.out.println(recvLine);
    				return true;
    			}
    			else
    			{
    				System.out.println(recvLine);
    				System.out.println("retry connection with \"unknown\" username");
    				ois.close();
    				oos.close();
    				s.close();
    			}
    	     }
    	     catch (IOException e)
    	     {  
    	        e.printStackTrace();
    	     }
    	     catch (Exception e)
    	     {  
    	        e.printStackTrace();
    	     }
    		return false;	
    	}
     
    	private static void communication()
    	{
    		String userCommand = "shutdown";
    		try
    		{
    			String serverAnswer = ois.readObject().toString();
    			if(serverAnswer.contains("student"))
    				student = (Student)ois.readObject();
    			else
    				username = "unknown";
     
    			while(exitValue != true)
    			{
    				System.out.println(username + "> ");
    				InputStreamReader in = new InputStreamReader(System.in);
    				BufferedReader entree = new BufferedReader(in);
    				userCommand = entree.readLine();
     
    				exitValue = controlCommand(userCommand);
    			}
     
    		}
    		catch(Exception e)
    		{
    			closeConnection(userCommand);
    			System.out.println(e);
    		}
    	}
     
    	private static boolean controlCommand(String command)
    	{
    		// Vérification des commandes utilisateur
    		...
    	}
     
    	private static void closeConnection(String command)
    	{
    		try
    		{
    			oos.writeObject(command);
    			oos.close();
    			ois.close();
    			s.close();
    		}
    		catch(IOException e)
    		{
    			System.out.println(e);
    		}
    	}
    }
    Pour le serveur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
     
    public class Serveur
    {
    	private static int port = 1000;
    	private ServerSocket server;
    	private Socket client;
    	private String fileName, line, connection;
    	private String article = ".\\Files\\articles\\";
    	private boolean validUser = false;
    	private static Student student;
    	private ObjectInputStream ois;
    	private ObjectOutputStream oos;
    	private Map<String, ServerProcess> map = new HashMap<String, ServerProcess>();
    	private static int number_unknown = 1;
    	private ThreadGroup tg = new ThreadGroup("Process_Client");
     
     
    	public Serveur()
    	{
    		try
    		{
    			server = new ServerSocket(port);
    			map.put("unknown", null);
     
    			while(true)
    			{
    				// wait for client connection
    				client = server.accept();
     
    				ois = new ObjectInputStream(client.getInputStream());
    				oos = new ObjectOutputStream(client.getOutputStream());
     
    				connection = ois.readObject().toString();
     
    				// check if user name is not already used
    				if((map.get(connection) != null) && (connection.compareTo("unknown") != 0))
    				{
    					oos.writeObject("username already used.");
    				}
    				else
    				{
    					validUser = false;
     
    					// Search user name in users' file
    					validUser = searchUser(connection);
     
    					// Create a thread for this user
    					newThread(validUser);
    				}
    			}
    		}
    		catch(Exception e)
    		{
    			System.out.println(e);
    		}
    	}
     
    	private boolean searchUser(String user)
    	{
    		boolean fileExistence = false;
    		try
    		{
    			// Vérification client
    		}
    		catch(Exception e)
    		{
    			if(fileExistence == false)
    				System.out.println("User's file not found.");
    			else
    				return false;
    		}
    		return false;
    	}
     
    	private void newThread(boolean valid)
    	{
    		try
    		{
    			// Give local time
    			Date actualDate = new Date();
    			SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
     
    			// Send answer
    			String welcome = dateFormat.format(actualDate) + ", " + connection + " welcome on 3CT201 server.";
    			oos.writeObject(welcome);
     
    			// Send student object if valid == true, else send "none" answer 
    			if(valid == true)
    			{
    				oos.writeObject("student");
    				oos.writeObject(student);
    				ServerProcess requet = new ServerProcess(client, student, ois, oos, map, tg);
    				requet.start();
    				map.put(connection, requet);
    			}
    			else
    			{
    				connection = "unknown" + number_unknown;
    				oos.writeObject("none");
    				ServerProcess requet = new ServerProcess(client, student, ois, oos, map, tg);
    				requet.start();
    				map.put(connection, requet);
    			}
    		}
    		catch(Exception e)
    		{
    			System.out.println(e);
    		}
    	}
     
    	public static void main(String[] args )
    	{  	
    	    try
    	    {
    	    	// Vérification argument plus instancie l'objet Server		
    	    }
    	    catch (Exception e)
    	    {
    	    	e.printStackTrace();
    	    }
    	}
    }
    Pour les thread serveur-client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    public class ServerProcess extends Thread
    {
    	private Socket client;
    	private Student student;
    	private ObjectInputStream ois;
    	private ObjectOutputStream oos;
    	private Map<String, ServerProcess> map;
    	private boolean end = false;
    	ThreadGroup tg;
     
    	public ServerProcess(Socket client, Student student, ObjectInputStream ois, 
    			ObjectOutputStream oos, Map<String, ServerProcess> map, ThreadGroup tg)
    	{
    		this.client = client;
    		this.student = student;
    		this.ois = ois;
    		this.oos = oos;
    		this.map = map;
    		this.tg = tg;
    	}
     
    	public void run()
    	{
    		try
    		{
    			while(!end)
    			{
    				if(!this.isInterrupted())
    					return;
     
    				// Traitement des commandes clients
    			}
    		}
    		catch(ClassNotFoundException e)
    		{
    			System.out.println(e);
    		}
    		catch(IOException e)
    		{
    			System.out.println(e);
    		}
    	}
     
    	// Fonctions de traitements
    	...
     
    	public void dispose()
    	{
    		try
    		{
    			oos.close();
    			ois.close();
    			client.close();
    		}
    		catch(IOException e)
    		{
    			System.out.println(e);
    		}
    	}
    }
    Comment se servir de la classe ThreadGroup pour stopper mes threads ?

    Si quelqu'un pouvais me dire se qu'il faut changer.

  5. #5
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    La première règle d'or est de n'utiliser aucune des méthodes deprecated.

    Après, tout est un jeu de boolean que le thread vient tcheker régulièrement, et ou de InterruptedException, et ou de synchronized, etc.

    Plutot que le ThreadGroup, voir plutôt les Executors. Regarde aussi les finesses d'usage de volatile, pratique je pense pour ton cas.

    Et regarde aussi les tutoriaux sur le sujet, qui n'est pas facile, mais tout de même très bien documenté.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    52
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 52
    Points : 63
    Points
    63
    Par défaut
    Un thread par client n'est pas viable pour les gros serveurs (> 1000 clients), vous pouvez regarder le package nio et ainsi utiliser les ServerSocketChannel et les Selector permettant de gérer plusieurs sockets avec un thread (Multiplexage des sockets réseau client). Ainsi que d'utiliser un TreadPoolExecutor pour traiter les données entrante ou sortante en fonction de leur temps de gestion. Un petit lien pour vous donner une idée http://www.scribd.com/doc/267405/-Java-NIO-with-Grizzly

  7. #7
    AkH
    AkH est déconnecté
    Membre du Club
    Homme Profil pro
    Perso
    Inscrit en
    Juillet 2005
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Perso

    Informations forums :
    Inscription : Juillet 2005
    Messages : 58
    Points : 52
    Points
    52
    Par défaut
    Merci beaucoup maisonneuve01 pour ton aide, mais mon serveur aura max 10/20 connexion en simultannées.

    J'ai trouvé mon affaire avec des bouléens.

    Arf je viens do mon C++ et les pointeur cachés en Java j'ai encore un peut de mal.

    Mon problème est donc résolu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. gestion des threads
    Par yanis97 dans le forum Langage
    Réponses: 6
    Dernier message: 20/04/2006, 12h41
  2. Gestion des Threads
    Par Nalfouille dans le forum MFC
    Réponses: 3
    Dernier message: 05/04/2006, 16h29
  3. Gestion des threads
    Par yanis97 dans le forum C++
    Réponses: 6
    Dernier message: 08/03/2006, 09h39
  4. GEstion des thread
    Par Julien Dufour dans le forum Access
    Réponses: 8
    Dernier message: 06/10/2004, 14h28
  5. [reseaux] Gestion des threads en perl
    Par totox17 dans le forum Programmation et administration système
    Réponses: 2
    Dernier message: 28/11/2002, 09h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo