Você está na página 1de 74

Threads e Sockets

POO

Prof. Márcio Delamaro

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 1/74


O que é
● Thread é uma forma de um processo dividir a si
mesmo em duas ou mais tarefas que podem
ser executadas concorrentemente.
● In computer science, a thread of execution is
the smallest sequence of programmed
instructions that can be managed
independently by a scheduler, which is typically
a part of the operating system.

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 2/74


Processo x thread
● The implementation of threads and processes
differs between operating systems, but in most
cases a thread is a component of a process.
Multiple threads can exist within one process.
Process

Thread #1 Thread #2

Time

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 3/74


Uma thread na JVM

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 4/74


Duas threads na JVM

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 5/74


Como criar
● Em Java, a criação de uma nova thread é
bastante simples
● Basta criar um objeto do tipo Thread
● Executar o método start()
● O método run() começa a executar

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 6/74


Hello thread?
public class HelloThread extends Thread {
public void run() {
   System.out.println("Hello thtread");
}

public static void main(String[] args) {
   HelloThread ht = new HelloThread();
   ht.start();
     System.out.println("Fim da thread principal");
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 7/74


Hello thread?
public class HelloThread extends Thread {
public void run() {
   System.out.println("Hello thtread");
}

public static void main(String[] args) {
   HelloThread ht = new HelloThread();
   ht.start();
     System.out.println("Fim da thread principal");
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 8/74


Hello thread?
public class HelloThread extends Thread {
public void run() {
   System.out.println("Hello thtread");
}

public static void main(String[] args) {
   HelloThread ht = new HelloThread();
   ht.start();
     System.out.println("Fim da thread principal");
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 9/74


Execução

ht = new(...)

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 10/74


Execução

ht = new(...)
ht.start()

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 11/74


Execução

ht = new(...)
ht.start()
println(...) println(...)

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 12/74


Execução

ht = new(...)
ht.start()
println(...) println(...)

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 13/74


Execução

ht = new(...)
ht.start()
println(...) println(...)

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 14/74


Hello muitas threads
● Vamos agora criar uma série de threads
● Vamos numerar cada uma delas
● E vamos colocá-las para executar

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 15/74


Muitas threads
private int nro;
public HelloThread(int n) {
nro = n;
}

public void run() {
System.out.println("Hello thtread " + nro);
}

public static void main(String[] args) {
for (int i = 0; i < 100; i++ ) {
HelloThread ht = new HelloThread(i);
ht.start();
    }
    System.out.println("Fim da thread principal");
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 16/74


Muitas threads
private int nro;
public HelloThread(int n) { Construtor guarda o número da Thread
nro = n;
}

public void run() {
System.out.println("Hello thtread " + nro);
}

public static void main(String[] args) {
for (int i = 0; i < 100; i++ ) {
HelloThread ht = new HelloThread(i); São criadas 100 Threads,
ht.start(); numeradas de 0 a 99
    }
    System.out.println("Fim da thread principal");
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 17/74


Ordem da saída
● Qual é a ordem de execução dos println?

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 18/74


Ordem da saída
● Qual é a ordem de execução dos println?
Hello thtread 0
Hello thtread 2
Hello thtread 1
Hello thtread 3
Hello thtread 4
Hello thtread 5
.
.
.
Hello thtread 69
Hello thtread 70
Hello thtread 71
Hello thtread 73
Hello thtread 75
Hello thtread 76
Hello thtread 77
Hello thtread 78

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 19/74


Ordem da saída
● Qual é a ordem de execução dos println?
Hello thtread 0 Hello thtread 0
Hello thtread 2 Hello thtread 1
Hello thtread 1 Hello thtread 2
Hello thtread 3 Hello thtread 3
Hello thtread 4 Hello thtread 6
Hello thtread 5 Hello thtread 4
. .
. .
. .
Hello thtread 69 Hello thtread 93
Hello thtread 70 Hello thtread 94
Hello thtread 71 Hello thtread 97
Hello thtread 73 Hello thtread 96
Hello thtread 75 Hello thtread 99
Hello thtread 76 Fim da thread
Hello thtread 77 principal
Hello thtread 78 Hello thtread 98

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 20/74


Ordem da saída
● Qual é a ordem de execução dos println?
Hello thtread 0 Hello thtread 0
Hello thtread 2 Hello thtread 1
Hello thtread 1 Hello thtread 2 Ou seja, não existe
Hello thtread 3 Hello thtread 3 um aordem definida
Hello thtread 4 Hello thtread 6 para execução das
Hello thtread 5 Hello thtread 4 threads.
. . Resultado não
. . determinístico!
. .
Hello thtread 69 Hello thtread 93
Hello thtread 70 Hello thtread 94
Hello thtread 71 Hello thtread 97
Hello thtread 73 Hello thtread 96
Hello thtread 75 Hello thtread 99
Hello thtread 76 Fim da thread
Hello thtread 77 principal
Hello thtread 78 Hello thtread 98

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 21/74


Caso prático
● Vamos voltar ao nosso exemplo GUI

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 22/74


Caso prático
● Vamos voltar ao nosso exemplo GUI
● Se o string digitado pelo usuário for um
número, vamos atualizando o label de 0 até o
numero
● Sugestão?

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 23/74


GUI
public void actionPerformed(ActionEvent e) {
int k = 0;
String s = nome.getText();
try {
    //transforma s para inteiro k
         //modifica label k vezes
}
catch (Exception ex) {
    // escreve Benvindo + s
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 24/74


GUI
public void actionPerformed(ActionEvent e) {
int k = 0;
String s = nome.getText();
try {
   k = Integer.parseInt(s);
     for ( int i = 0; i <= k; i++) {
     s = WELLCOME + " " + i;
     label.setText(s);
   }
}
catch (Exception ex) {
    label.setText(WELLCOME + " " + s);
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 25/74


GUI
public void actionPerformed(ActionEvent e) {
int k = 0;
String s = nome.getText();
try {
   k = Integer.parseInt(s);
     for ( int i = 0; i <= k; i++) {
     s = WELLCOME + " " + i;
     label.setText(s);
   }
}
catch (Exception ex) {
    label.setText(WELLCOME + " " + s);
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 26/74


Como funciona a GUI
Swing fica monitorando a interface,
esperando um evento.

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 27/74


Como funciona a GUI
Swing fica monitorando a interface,
esperando um evento.

Ev
en
to
oc
orr
eu

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 28/74


Como funciona a GUI
Swing fica monitorando a interface,
esperando um evento.

Ev
en
to
oc
orr
eu

actionPerformed(Event e)

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 29/74


Como funciona a GUI
Swing fica monitorando a interface,
esperando um evento.

Ev
en
to
oc
orr
eu

actionPerformed(Event e)
Return

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 30/74


Como funciona a GUI
Swing fica monitorando a interface,
esperando um evento.

Swing vai atualizar os componentes


que precisam ser atualizados.

Ev
en
to
oc
orr
eu

actionPerformed(Event e)
Return

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 31/74


Então...
● Qual seria a solução?

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 32/74


Então...
● Qual seria a solução?
● Permitir que as duas coisas seja feitas ao
mesmo tempo
– O programa atualiza o componente
– O swing atualiza a interface

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 33/74


Implementando
public void actionPerformed(ActionEvent e) {
int k = 0;
String s = nome.getText();
try {
    //transforma s para inteiro k
         // cria um thread que modifica 
         // label k vezes
}
catch (Exception ex) {
    // escreve Benvindo + s
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 34/74


Implementando
public void actionPerformed(ActionEvent e) {
int k = 0;
String s = nome.getText();
try {
    //transforma s para inteiro k
         // cria um thread que modifica 
         // label k vezes O que é necessário dentro
dessa thread?
}
catch (Exception ex) {
    // escreve Benvindo + s
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 35/74


Implementando
public void actionPerformed(ActionEvent e) {
int k = 0;
String s = nome.getText();
try {
    //transforma s para inteiro k
         // cria um thread que modifica 
         // label k vezes O que é necessário dentro
dessa thread?
} Componente e valor de k!!!
catch (Exception ex) {
    // escreve Benvindo + s
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 36/74


Implementando...
public void actionPerformed(ActionEvent e) {
    int k = 0;
    String s = nome.getText();
    try {
      k = Integer.parseInt(s);
    new AtuaThread(label, k).start();
    }
    catch (Exception ex) {
       label.setText(WELLCOME + " " + s);
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 37/74


Implementando...
public void actionPerformed(ActionEvent e) {
    int k = 0;
    String s = nome.getText();
    try {
      k = Integer.parseInt(s);
    new AtuaThread(label, k).start();
    }
    catch (Exception ex) {
       label.setText(WELLCOME + " " + s);
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 38/74


Implementando a thread
Public class AtuaThread extends Thread{
private JLabel jl;
private int n;

public AtuaThread(JLabel label, int k) {
jl = label;
n = k;
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 39/74


Implementando a thread
public void run() {
String s;
for ( int i = 0; i <= n; i++) {
s = WELLCOME + " " + i;
label.setText(s);
}
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 40/74


Corrida de threads

Disparar um certo número de threads.


Cada uma associada a um slider.

A thread dorme um tempinho. Depois


incrementa o slider.

Até atingir um determinado limite

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 41/74


Corrida de threads

Disparar um certo número de threads.


Cada uma associada a um slider.

A thread dorme um tempinho. Depois


incrementa o slider.

Até atingir um determinado limite

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 42/74


Como organizar

Controlador

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 43/74


Como organizar

Dispara uma série de


Controlador Runners

Runner Runner Runner Runner

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 44/74


Como organizar

Dispara uma série de


Controlador Runners

Runner Runner Runner Runner

Dorme um pouquinho.
Incrementa o slider.

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 45/74


Como organizar

Dispara uma série de


Controlador Runners

Fica esperando até


que a primeira
thread termine

Runner Runner Runner Runner

Dorme um pouquinho.
Incrementa o slider.
Quando chegar no limite,
tenta avisar o controlador.

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 46/74


Runners
public class Runner extends Thread
{
String name;
Controlador ct;
int len, sleep;
JProgressBar pb;
public Runner(Controlador c, String n, JProgressBar jpb, int 
sl, int x)
{
   ct = c;
   name = n;
   len = x;
   sleep = sl;
   pb = jpb;
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 47/74


Runners
public void run() {
   for (int i = 0; i < len; i++) {
      try {
         Thread.sleep(sleep);
      }
    catch (Exception e) {
       ;
      }
      if ( ct.getFirst() != null )break;
      pb.setValue(i+1);
   }
   ct.setFirst(name);
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 48/74


Runners
public void run() {
   for (int i = 0; i < len; i++) {
      try {
         Thread.sleep(sleep);
      }
    catch (Exception e) {
       ;
      }
      if ( ct.getFirst() != null )break;
      pb.setValue(i+1);
   }
   ct.setFirst(name);
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 49/74


Runners
public void run() {
O Runner roda até chegar no
   for (int i = 0; i < len; i++) { limite ou até que algum outro
Runner termine.
      try {
         Thread.sleep(sleep);
      }
    catch (Exception e) {
       ;
      }
      if ( ct.getFirst() != null )break;
      pb.setValue(i+1);
   }
   ct.setFirst(name);
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 50/74


Controlador
public Controlador(int n, int x, int s,
               JProgressBar[] jpb, JLabel jl)
{
nRunners = n;
len = x;
sleep = s;
pb = jpb;
result = jl;
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 51/74


Controlador
public void run() {
   for (int i = 0; i < nRunners; i++) {
      Runner r = new Runner(this, "Corredor " + (i+1), 
                  pb[i],sleep, len);
      r.start();
   }
   do {
      try {
         Thread.sleep(10);
      }
      catch (Exception e) {;}
    } while ( getFirst() == null);
    result.setText(getFirst());
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 52/74


Controlador
String first = null;

    public void setFirst(String s) {
     if ( first == null )
         first = s;
    }
    
    public String getFirst(){
        return first;
    }

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 53/74


O problema...
● O problema é que o controlador é
compartilhado com todos os Runners
● Um seja, todos têm acesso à variável que
controla o final da corrida
● Para que não haja confusão é preciso
sincronizar o acesso a essa variável

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 54/74


Controlador
String first = null;

    public synchronized void setFirst(String s) {
     if ( first == null )
         first = s;
    }
    
    public synchronized String getFirst(){
        return first;
    }

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 55/74


Controlador
String first = null;

    public synchronized void setFirst(String s) {
     if ( first == null )
         first = s; Somente uma thread pode acessar um
método sincronizado do mesmo objeto.
    }
    
    public synchronized String getFirst(){
        return first;
    }

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 56/74


Synchronized
● It is not possible for two invocations of synchronized
methods on the same object to interleave. When one
thread is executing a synchronized method for an object,
all other threads that invoke synchronized methods for
the same object block (suspend execution) until the first
thread is done with the object.
● Synchronized methods enable a simple strategy for
preventing thread interference and memory consistency
errors: if an object is visible to more than one thread, all
reads or writes to that object's variables are done
through synchronized methods.

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 57/74


Aproveitando...
● Sockets são canais que permitem que
mensagens sejam trocadas entre duas
máquinas
● Estrutura cliente servidor

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 58/74


Aproveitando...
● Sockets são canais que permitem que
mensagens sejam trocadas entre duas
máquinas
● Estrutura cliente servidor

Servidor

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 59/74


Aproveitando...
● Sockets são canais que permitem que
mensagens sejam trocadas entre duas
máquinas
● Estrutura cliente servidor
Servidor se instala numa
Servidor porta.
Espera alguém se
conectar

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 60/74


Aproveitando...
● Sockets são canais que permitem que
mensagens sejam trocadas entre duas
máquinas
● Estrutura cliente servidor
Cliente se conecta usando
IP + porta
Servidor se instala numa
Servidor porta. Cliente
Espera alguém se
conectar

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 61/74


Aproveitando...
● Sockets são canais que permitem que
mensagens sejam trocadas entre duas
máquinas
● Estrutura cliente servidor
Cliente se conecta usando
IP + porta
Servidor se instala numa
Servidor porta. Cliente
Espera alguém se
conectar

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 62/74


Servidor
public static void main(String[] args) throws 
Exception {
   ServerSocket servidor = new ServerSocket(9669);
    System.out.println("Porta 9669 aberta!");
    Socket cliente = servidor.accept();
    System.out.println("Nova conexão com o cliente 
" + cliente.getInetAddress().getHostAddress());

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 63/74


Servidor
public static void main(String[] args) throws 
Exception {
   ServerSocket servidor = new ServerSocket(9669);
    System.out.println("Porta 9669 aberta!");
    Socket cliente = servidor.accept();
    System.out.println("Nova conexão com o cliente 
" + cliente.getInetAddress().getHostAddress());

Reserva a porta 9669

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 64/74


Servidor
public static void main(String[] args) throws 
Exception {
   ServerSocket servidor = new ServerSocket(9669);
    System.out.println("Porta 9669 aberta!");
    Socket cliente = servidor.accept();
    System.out.println("Nova conexão com o cliente 
" + cliente.getInetAddress().getHostAddress());

Reserva a porta 9669 Fica esperando até que algum


cliente se conecte

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 65/74


Cliente
public static void main(String[] args) throws 
Exception {
Socket cliente = new Socket("127.0.0.1",9669);
System.out.println("O cliente se conectou ao 
servidor!");

Conecta-se com o servidor. Se o servidor não estiver pronto, um


erro ocorre.

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 66/74


Conectados
● Após isso, os dois programas podem trocar
informações
● Escrever ou ler
● Como um InputStream e OutputStream

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 67/74


Servidor
PrintStream saida = new 
          PrintStream(cliente.getOutputStream());

Scanner s = new Scanner(cliente.getInputStream());
while (s.hasNextLine()) {
  String r = s.nextLine();
  System.out.println(r);
  saida.println("Recebido: " + r);
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 68/74


Servidor
PrintStream saida = new 
          PrintStream(cliente.getOutputStream());

Scanner s = new Scanner(cliente.getInputStream());
while (s.hasNextLine()) {
  String r = s.nextLine();
  System.out.println(r);
  saida.println("Recebido: " + r);
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 69/74


Cliente
PrintStream saida = new 
          PrintStream(cliente.getOutputStream());
Scanner teclado = new Scanner(System.in);
Scanner server = new 
               Scanner(cliente.getInputStream());

while (teclado.hasNextLine()) {
  saida.println(teclado.nextLine());
  System.out.println(server.nextLine());
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 70/74


Múltiplos clientes
● É possível conectar diversos clientes à mesma
porta de um servidor
● Mas para isso é preciso que o servidor trate
cada uma das conexões
● Sugestões?

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 71/74


Múltiplos clientes
● É possível conectar diversos clientes à mesma
porta de um servidor
● Mas para isso é preciso que o servidor trate
cada uma das conexões
● Cada cliente é tratado por uma thread

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 72/74


Servidor
public static void main(String[] args) throws Exception {
       ServerSocket servidor = new ServerSocket(9669);
     System.out.println("Porta 9669 aberta!");
     
     while (true) {
        Socket cliente = servidor.accept();
        Thread st = new ServerThread(cliente);
        st.start();
     }
     
}

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 73/74


ServerThread
public void run() {
     System.out.println("Nova conexão com o cliente " +   
          cliente.getInetAddress().getHostAddress()
        ); 
        PrintStream saida = new PrintStream(cliente.getOutputStream());
        Scanner s = new Scanner(cliente.getInputStream());
        while (s.hasNextLine()) {
          String r = s.nextLine();
          System.out.println(r);
          saida.println("Recebido: " + r);
        }
   System.out.println("Fim da conexao com " + 
                         cliente.getInetAddress().getHostAddress());

Programação Orientada a Objetos – Prof Marcio Delamaro – ICMC/USP 74/74