Threads em Java

5 respostas
M

Opa Galera sou iniciante em Java e estou precisando criar uma Thread que fique executando enquanto um cliente estiver conectado via socket.

5 Respostas

S
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" Start.");
                System.out.println(Thread.currentThread().getName()+" End.");
            }
        }, delay, intervalo em milissegundos);
lvbarbosa

Você quer que cada conexão seja tratada em uma thread separada?

import java.net.Socket;
import java.net.ServerSocket;
import java.io.IOException;

class Main {
    public static void main(String[] args) {
        int porta = leEntrada(args);
        try {
            ServerSocket server = new ServerSocket(porta);
            while (true) {
                Socket client = server.accept();
                new Thread(codigoExecutadoPelaThread(client)).start();
            }
        } catch (IOException ex) {
            System.err.println("Ocorreu um erro na thread principal do servidor.");
            ex.printStackTrace();
        }
    }

    public static int leEntrada(String[] args) {
        int porta = -1;
        try {
            porta = Integer.parseInt(args[0]);
        } catch (NumberFormatException | ArrayIndexOutOfBoundsException ex) {
            System.err.println("Chamda inválida. Uso: java Main <porta>");
            System.exit(1);
        }
        return porta;
    }

    public static Runnable codigoExecutadoPelaThread(Socket client) {
        return () -> {
            // aqui você coloca o código que vai ser executado numa nova thread,
            // que utiliza o client.
            // Eu acho melhor você criar uma classe que implementa a interface Runnable,
            // mas isso aqui vai servir.
            try {
                client.close();
            } catch (IOException ex) {
                System.err.println("Erro ao tentar fechar o socket.");
                ex.printStackTrace();
            }
        };
    }

}
M

Assim. Quero fazer uma Thread com socketServer que fique esperando conexões de cliente. Cada cliente terá um socketServer e uma porta. Quando um cliente desconectar ele enviara para essa Thread uma String “Fim” antes de desconectar. Ao se desconectar a Thread deverá novamente aguardar conexões deste mesmo cliente. Pra ser mais exato serão 4 clientes.

Desculpem a gambiarra mas estou aprendendo:

private void iniciarServidor()

{

try {

serverSocket5 = new ServerSocket (2345);

serverSocket6 = new ServerSocket (2346);

serverSocket7 = new ServerSocket (2347);

serverSocket8 = new ServerSocket (2348);

jLabelServidor.setText(Servidor Online);

} catch (IOException ex) {

Logger.getLogger(Menu_Jf.class.getName()).log(Level.SEVERE, null, ex);

}
new Thread()
    {
    public void run()
    {
   
    try
        {    
        while(true)
        {
            Socket socket5 = serverSocket5.accept();
        if (socket5.isBound()== true)
        {
          JOptionPane.showMessageDialog(null,"Leitor 5. Conexão Iniciada com IP:  \n"+socket5.getInetAddress().toString()+"Porta: "+socket5.getPort());
          Recebido = new DataInputStream(socket5.getInputStream());
          if(Recebido.readUTF().equals("FIM"))
          {
          //JOptionPane.showMessageDialog(null,"Leitor 5 desconectou");
          Recebido = null;
          }
          }

/////Aqui gostaria que a Thread voltasse a esperar conexão do mesmo cliente que desconectou como um loop que fica atualizando se o cliente esta conectado.

}.start(); ///

Como sou iniciante em java e ainda mais em Thread não entendi exatamente como funciona uma Thread para ela ficar executando em segundo plano junto ao main. Desde já agradeço a ajuda

lvbarbosa

Vou assumir que você entendeu como funcionam threads no sistema operacional. Quando você cria um objeto do tipo Thread, esse objeto representa uma thread física do sistema. Ao chamar o método start, você inicializa a execução em paralelo dessa thread criada.

Thread t = new Thread(runnable);
// essa chamada ao método start() retorna imediatamente,
// e a thread que estamos agora continua
// executando normalmente.
t.start();
outraOperacao();
outraOperacao();
//...

Quando chamamos o start(), a nova thread começa sua execução, de forma independente à thread que a criou, um fluxo de execução completamente diferente. É como se fossem dois programas rodando agora.

O seu raciocínio é o seguinte, pelo que eu entendi: você quer uma thread dedicada para cada cliente, correto? Eu faria de uma maneira um pouquinho diferente, como mandei no exemplo para você ali antes.

  1. A thread principal abre o servidor e espera conexões infinitamente
  2. Quando chega uma nova conexão (ou seja, quando o método accept() retorna), uma nova thread é criada para se comunicar com o cliente
  3. No código da thread, eu faria com que o cliente se identificasse (com um número ou uma string, por exemplo), e a partir daí saberia o que fazer.

Porém, vou tentar te dar algumas ideias do que fazer para continuar com a tua linha de raciocínio.

Você pode fazer o seguinte:

  1. Continuar o que fez, associando de forma fixa uma porta para cada cliente;
  2. Cria uma classe que herda de Thread, e implementa o método run. Para o objeto dessa nova classe, você vai passar qualquer tipo de informação de contexto necessária para que ele identifique o cliente.
  3. O método run vai ficar escutando na porta determinada para o cliente, e quando chegar uma conexão, vai saber o que fazer (baseado nos parâmetros passados)

Vou tentar exemplificar isso da forma mais sucinta possível, para que tu entenda e generalize para o teu caso específico, ok?

Vamos lá:

import java.net.Socket;
import java.net.ServerSocket;
import java.io.IOException;

class Main {

    public static void main(String[] args) {
        ThreadCustomizada t1 = new ThreadCustomizada(2345, "Cliente 1");
        ThreadCustomizada t2 = new ThreadCustomizada(2346, "Cliente 2");
        ThreadCustomizada t3 = new ThreadCustomizada(2347, "Cliente 3");
        ThreadCustomizada t4 = new ThreadCustomizada(2348, "Cliente 4");
        // até aqui tem apenas 1 thread rodando (na verdade tem outras, o Garbage Collector por exemplo, mas enfim)
        t1.start(); // a partir daqui existem 2 threads rodando
        t2.start(); // 3 agora
        t3.start(); // 4
        t4.start(); // 5 threads rodando

        // aqui a thread principal morre quando acaba o método main,
        // mas as outras 4 estão executando, por isso o programa continua até que todas morram
    }
}

class ThreadCustomizada extends Thread {
    private final int porta;
    private final String nomeDoCliente;
    /*
        pode passar o que quiser pro construtor,
        tudo o que for necessário para lidar com o cliente
    */
    ThreadCustomizada(int porta, String nomeDoCliente) {
        this.porta = porta;
        this.nomeDoCliente = nomeDoCliente;
    }
    @Override
    public void run() {
        try {
            ServerSocket server = new ServerSocket(this.porta);

            // Fica esperando o cliente se conectar sempre
            while (true) {
                // essa chamada bloqueia (fica travada, não sai do lugar)
                // até que o cliente se conecte. Quando isso acontecer,
                // o método accept retorna e a execução continua.
                Socket client = server.accept();
                // aqui você faz tudo o que quiser com o socket
                // no momento que o cliente sair, o while reinicia
                // e fica esperando por aquele cliente específico novamente,
                // na mesma porta
                client.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
M

Obrigadão pela ajuda, era isso mesmo que eu queria fazer. Só agora estou com um problema quanto as portas de cada socket. Pois quando o cliente 2 se conecta e o 1 está desconectado ele não respeita o número da porta setado e utiliza o socket do Cliente 1. Desde já muito obrigado pela ajuda.

Criado 23 de março de 2017
Ultima resposta 27 de mar. de 2017
Respostas 5
Participantes 3