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():
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.
publicvoidrun(){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) { }}
S
spiderman
Vlw. Pela dica. tanks.
E
entanglement
spiderman:
A função dessa thread é ficar aguardando um valor ser inserido na lista
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.
E
entanglement
Exemplo. Aqui temos 5 threads que produzem dados, e 1 que consome dados. Todas elas são conectadas por uma java.util.concurrent.BlockingQueue.
importjava.util.Random;importjava.util.concurrent.BlockingQueue;importjava.util.concurrent.LinkedBlockingQueue;importjava.util.concurrent.TimeUnit;classDado{publicDado(intid,Stringorigem){this.id=id;this.origem=origem;}privateintid;privateStringorigem;publicintgetId(){returnid;}publicStringgetOrigem(){returnorigem;}@OverridepublicStringtoString(){return"("+id+","+origem+")";}}classThreadProdutoraimplementsRunnable{publicThreadProdutora(BlockingQueue<Dado>fila,Stringnome){this.fila=fila;this.nome=nome;cancel=false;}publicvoidaddDado(intid)throwsInterruptedException{fila.put(newDado(id,nome));}@Overridepublicvoidrun(){intid=0;try{while(!cancel){Thread.sleep(r.nextInt(1000));addDado(id);id++;}System.out.println("Execução da thread produtora "+nome+" cancelada.");}catch(InterruptedExceptionex){System.out.println("Execução da thread produtora "+nome+" interrompida.");}}publicvoidcancelar(){cancel=true;}privateBlockingQueue<Dado>fila;privateStringnome;privatevolatilebooleancancel;privatestaticRandomr=newRandom();}classThreadConsumidoraimplementsRunnable{publicThreadConsumidora(BlockingQueue<Dado>fila){this.fila=fila;}@Overridepublicvoidrun(){try{while(!cancel){Dadodado=fila.poll(1000,TimeUnit.MILLISECONDS);// experimente trocar 1000 por 100 por curiosidade.if(dado!=null)System.out.println(dado);elseSystem.out.println("Fila vazia, esperando...");}System.out.println("Execução da thread consumidora cancelada.");}catch(InterruptedExceptionex){System.out.println("Execução da thread consumidora interrompida.");}}privateBlockingQueue<Dado>fila;privatevolatilebooleancancel;}/** */publicclassExemploBlockingQueue{publicstaticvoidmain(String[]args){System.out.println("Início dos testes.");BlockingQueue<Dado>fila=newLinkedBlockingQueue<Dado>();ThreadthrConsumidora=newThread(newThreadConsumidora(fila));Thread[]thrProdutora=newThread[5];for(inti=0;i<thrProdutora.length;++i)thrProdutora[i]=newThread(newThreadProdutora(fila,"tp"+i));thrConsumidora.start();for(inti=0;i<thrProdutora.length;++i)thrProdutora[i].start();// Vamos deixar o teste rodando por apenas 10 segundostry{Thread.sleep(10000);thrConsumidora.interrupt();for(inti=0;i<thrProdutora.length;++i)thrProdutora[i].interrupt();thrConsumidora.join();for(inti=0;i<thrProdutora.length;++i)thrProdutora[i].join();}catch(InterruptedExceptionex){}System.out.println("Fim dos testes.");}}