No entiendo planteamiento de un Thread

Iniciado por Zoik, 11 Septiembre 2013, 11:02 AM

0 Miembros y 1 Visitante están viendo este tema.

Zoik

Bien estoy trasteando con sockets, y me tope con uno de los tutoriales de Chuidiang, que haría yo sin su wiki  ;D.

Aqui esta el link:

http://www.chuidiang.com/java/sockets/hilos/socket_hilos.php

Código (java) [Seleccionar]
HiloDeCliente.java
// Implementa Runnable para poder ser lanzada en un hilo aparte
public class HiloDeCliente implements Runnable
{
  // En el constructor recibe y guarda los parámetros que sean necesarios.
  // En este caso una lista con toda la conversación y el socket que debe
  // atender.
  public HiloDeCliente(DefaultListModel charla, Socket socket)
  {
     ...
  }

  public void run ()
  {
     while (true)
     {
        // Código para atender al cliente.
     }
  }
}


Código (java) [Seleccionar]
ServidorChat.java
public class ServidorChat
{
  // Para guardar toda la conversación.
  private DefaultListModel charla = new DefaultListModel();

  public ServidorChat()
  {
     // Se crea el socket servidor
     ServerSocket socketServidor = new ServerSocket(5557);

     // Bucle infinito
     while (true)
     {
         // Se espera y acepta un nuevo cliente
         Socket cliente = socketServidor.accept();

         // Se instancia una clase para atender al cliente y se lanza en
         // un hilo aparte.
         Runnable nuevoCliente = new HiloDeCliente(charla, cliente);
         Thread hilo = new Thread(nuevoCliente);
         hilo.start();      
     }
  }
}


Mi pregunta esta en el Runnable de el bucle while, porque hace:

Código (java) [Seleccionar]
Runnable nuevoCliente = new HiloDeCliente(charla, cliente);
         Thread hilo = new Thread(nuevoCliente);


No sería mas directo hacer:

Código (java) [Seleccionar]
HiloDeCliente nuevoCliente = new HiloDeCliente(charla, cliente);

Y extender la class HiloDeCliente de Thread?

Es decir porque implementa un Runnable y la pone "dentro" de un Thread puediendo lanzar un Thread directamente.

Si alguien puediese explicarmelo lo agradeceria mucho.

Un saludo y gracias de antemano.

Alien-Z

#1
CitarMi pregunta esta en el Runnable de el bucle while, porque hace:

Código (java) [Seleccionar]
Runnable nuevoCliente = new HiloDeCliente(charla, cliente);
         Thread hilo = new Thread(nuevoCliente);


No sería mas directo hacer:

Código (java) [Seleccionar]
HiloDeCliente nuevoCliente = new HiloDeCliente(charla, cliente);

Y extender la class HiloDeCliente de Thread?

Es decir porque implementa un Runnable y la pone "dentro" de un Thread puediendo lanzar un Thread directamente.

Te lo pone en el comentario:

Código (java) [Seleccionar]
HiloDeCliente.java
// Implementa Runnable para poder ser lanzada en un hilo aparte
public class HiloDeCliente implements Runnable
{
  ...
}


Tiene que implementar la interfaz Runnable para poder ser lanzada en un hilo distinto. Esta manera de crear el hilo...

Código (java) [Seleccionar]
Runnable nuevoCliente = new HiloDeCliente(charla, cliente);
         Thread hilo = new Thread(nuevoCliente);


...se debe a que la clase Thread tiene un constructor que acepta como parámetro un objeto de tipo Runnable:

Código (java) [Seleccionar]
Thread(Runnable target) {
  ...
}


Por tanto aplica polimorfismo para poder crear un hilo con ese parámetro. Aún así, el polimorfismo ya se utiliza internamente, aqui no es necesario; esto también funcionaria:

Código (java) [Seleccionar]
HiloDeCliente nuevoCliente = new HiloDeCliente(charla, cliente);
         Thread hilo = new Thread(nuevoCliente);


Le mandamos un objeto de tipo "HiloDeCliente" pero el constructor debe recibir "Runnable", como "HiloDeCliente" implementa la interfaz "Runnable" (es un tipo padre) se aplica polimorfismo y tenemos el mismo resultado.

Saludos.

Zoik

Bien, gracias por tu rápida respuesta.

Yo lo e hecho de esta manera, sin Runnable, por eso quería saber si tal y como yo lo hago esta bien.

Código (java) [Seleccionar]
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.DefaultListModel;


public class Server {

private DefaultListModel<String> allMessages = new DefaultListModel<String>();

public Server(){
try {
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(9000);
while(true){
Socket newClientSocket = serverSocket.accept();
ThreadOfClient newClientThread = new ThreadOfClient(allMessages,newClientSocket);
newClientThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}


Código (java) [Seleccionar]
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

import javax.swing.DefaultListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;


public class ThreadOfClient extends Thread implements ListDataListener{

private DefaultListModel<String> allMessages = new DefaultListModel<String>();
private DataInputStream input;
private DataOutputStream output;

public ThreadOfClient(DefaultListModel<String> allMessages, Socket socket){
this.allMessages = allMessages;
try {
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
this.allMessages.addListDataListener(this);
} catch (Exception e) {
e.printStackTrace();
}
}

public void run(){
try {
while(true){
String messageOfServer = input.readUTF();
synchronized(allMessages){
allMessages.addElement(messageOfServer);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public void contentsChanged(ListDataEvent e) {


}

@Override
public void intervalAdded(ListDataEvent e) {
String text = (String) allMessages.getElementAt(e.getIndex0());
try {
output.writeUTF(text);
} catch (Exception exception) {
exception.printStackTrace();
}

}

@Override
public void intervalRemoved(ListDataEvent e) {


}
}



Un saludo y como siempre mil gracias ;)