Olá estou com uma dúvida referente ao uso de thread e while(true). tenho a seguinte situação ocorrendo, quando eu dou um .start em uma thread que possuo o processamento da máquina vai a 100% não estou entendendo o porque dessa situação. A função dessa thread é ficar aguardando um valor ser inserido na lista. Vejam meu código do public run():
public void run() {
boolean running = true;
while (running) {
try {
while (!List.isEmpty() && !SizeList.isEmpty()) {
System.out.println("\t\t Recebi valor "\n");
}
} catch (Exception e) {
}
}
}
Ele vai a 100% pq sua thread roda o while sem parar, ocupando totalmente o processador. Ela checa incessantemente se variável mudou ou não, a cada milissegundo, sempre que houver processador disponível.
Para corrigir isso, faça sua thread dormir um pouco. Por exemplo, verifique a variável a cada 0.2 segundos.
public void run() {
try {
while (List.isEmpty() && SizeList.isEmpty() && !Thread.interrupted()) {
Thread.sleep(200); //Para por 0.2s
}
System.out.println("\t\t Recebi valor "\n");
} catch (Exception e) {
}
}
[quote=spiderman]A função dessa thread é ficar aguardando um valor ser inserido na lista
[/quote]
Use um java.util.concurrent.BlockingQueue em vez de um ArrayList normal. Ele faz com que uma thread que espera algum valor ser inserido na fila espere até que outra thread insira um dado na lista. É mais eficiente que ficar esperando “em vazio” e mais seguro.
Exemplo. Aqui temos 5 threads que produzem dados, e 1 que consome dados. Todas elas são conectadas por uma java.util.concurrent.BlockingQueue.
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
class Dado {
public Dado (int id, String origem) {
this.id = id;
this.origem = origem;
}
private int id;
private String origem;
public int getId() { return id; }
public String getOrigem() { return origem; }
@Override public String toString() { return "(" + id + "," + origem + ")"; }
}
class ThreadProdutora implements Runnable {
public ThreadProdutora (BlockingQueue<Dado> fila, String nome) {
this.fila = fila;
this.nome = nome;
cancel = false;
}
public void addDado (int id) throws InterruptedException {
fila.put(new Dado (id, nome));
}
@Override public void run() {
int id = 0;
try {
while (!cancel) {
Thread.sleep(r.nextInt (1000));
addDado (id);
id++;
}
System.out.println ("Execução da thread produtora " + nome + " cancelada.");
} catch (InterruptedException ex) {
System.out.println ("Execução da thread produtora " + nome + " interrompida.");
}
}
public void cancelar() {
cancel = true;
}
private BlockingQueue<Dado> fila;
private String nome;
private volatile boolean cancel;
private static Random r = new Random();
}
class ThreadConsumidora implements Runnable {
public ThreadConsumidora (BlockingQueue<Dado> fila) {
this.fila = fila;
}
@Override public void run() {
try {
while (!cancel) {
Dado dado = fila.poll (1000, TimeUnit.MILLISECONDS); // experimente trocar 1000 por 100 por curiosidade.
if (dado != null)
System.out.println (dado);
else
System.out.println ("Fila vazia, esperando...");
}
System.out.println ("Execução da thread consumidora cancelada.");
} catch (InterruptedException ex) {
System.out.println ("Execução da thread consumidora interrompida.");
}
}
private BlockingQueue<Dado> fila;
private volatile boolean cancel;
}
/**
*/
public class ExemploBlockingQueue {
public static void main(String[] args) {
System.out.println ("Início dos testes.");
BlockingQueue<Dado> fila = new LinkedBlockingQueue<Dado>();
Thread thrConsumidora = new Thread (new ThreadConsumidora (fila));
Thread[] thrProdutora = new Thread[5];
for (int i = 0; i < thrProdutora.length; ++i)
thrProdutora[i] = new Thread (new ThreadProdutora (fila, "tp" + i));
thrConsumidora.start();
for (int i = 0; i < thrProdutora.length; ++i)
thrProdutora[i].start();
// Vamos deixar o teste rodando por apenas 10 segundos
try {
Thread.sleep (10000);
thrConsumidora.interrupt();
for (int i = 0; i < thrProdutora.length; ++i)
thrProdutora[i].interrupt();
thrConsumidora.join();
for (int i = 0; i < thrProdutora.length; ++i)
thrProdutora[i].join();
} catch (InterruptedException ex) {}
System.out.println ("Fim dos testes.");
}
}