Problema com Thread's

Olá pessoal, é a segunda vez que posto aqui no fórum, se estou no lugar errado desculpem.

Alguém sabe dizer por que minha classe não funciona?

Era para o loop da thread verificar a variavel value e imprimir caso seja diferente de null, mas quando rodo imprime só um "PrinterTest 9" e sai.

public class PrinterThread {
  
  private static String value;
  
  private Thread t;
  
  private boolean run;
  
  
  public PrinterThread() {
    run = true;
    value = "";

    t = new Thread(new Runnable() {

        public void run() {

          while(run)
            printAndNull();

        }//run
    });

  }//method()
  
  
  public void start() {
    run = true;
    t.start();
  }//method()
  
  
  public void stop() {
    run = false;
  }//method()
  
  
  public synchronized void print(String s) {
    value = s;
  }//method()
  
  
  public synchronized void printAndNull() {

    if(value != null) {
      System.out.println(value);

      value = null;
    }//if

  }//method()
  
  
  public static void main(String[] args) {
    
    PrinterThread p = new PrinterThread();
    p.start();
    
    for(int i = 0; i < 10; i++) {
      p.print("PrinterTest "+ String.valueOf(i));
    }//for
    
    p.stop();
  }//method()
  
}//class

Veja este trecho:

[code]p.start();

for(int i = 0; i < 10; i++) {
p.print("PrinterTest "+ String.valueOf(i));
}//for

p.stop();[/code]
O problema é que entre o start e o stop não existe nenhuma garantia que a thread terá a chance de entrar em execução. Ou seja, você dá o p.start(), seta o valor a ser impresso diversas vezes, dá p.stop() e o seu loop principal da classe PrinterThread pode não ter nem mesmo iniciado. Ou no seu caso, ele entrou depois que value tinha sido setado para 9.

Vale lembrar que isso não é defeito, a JVM e/ou sistema operacional decidem ao gosto deles o tempo que cada thread permanecerá em execução antes de dar a chance para outra.

Mas existem formas de resolver, pode tentar descobrir se quiser… precisando de ajuda estamos aí :wink:

No caso apenas para quem sabe poder dar uma enriquecida, tanto o windows quanto a jvm tratam o escalonamento de processos de forma preemptiva (utilizando politicas de escalonamento para controlar o fluxo de execução), ou seja eles interferem no processamento dos processos, adotando uma regra para execução de cada processo.

Valeu pessoal!

Descobri como garantir a execução de PrinterThread, tudo bem que a performance fica meio prejudicada, mas funciona. Acho que nesse caso é mais uma gambiarra do que uma solução.

Eu adicionei Thread.yield() no for.

  public static void main(String[] args) {  
      
    PrinterThread p = new PrinterThread();  
    p.start();  
      
    for(int i = 0; i &lt; 10; i++) {  
      p.print(&quot;PrinterTest &quot;+ String.valueOf(i));  

      //&quot;gambi&quot;
      Thread.yield();

    }//for  
      
    p.stop();  
  }//method()

[quote=juno.rr]Valeu pessoal!

Descobri como garantir a execução de PrinterThread, tudo bem que a performance fica meio prejudicada, mas funciona. Acho que nesse caso é mais uma gambiarra do que uma solução.

Eu adicionei Thread.yield() no for.
[/quote]

Acredito que uma solução mais “elegante” seria usar uma fila para armazenar e imprimir os valores dentro da thread PrintThread, assim como remover a “espera ocupada” (busy waiting) do método run(). Segue o código-fonte em anexo.

Att.,
Marcos Hack.

Muito legal Marcos. Agora sim temos uma solução.

Valeu pela força!