Situação embaraçosa com Threads

4 respostas
sk2ck

Pessoal tenho o seguinte codigo:

package br.com.rad.radiocog;

import java.util.ArrayList;

public class Estudos2{
  public static void main(String[] args) throws InterruptedException{
    Ar ar1 = new Ar();
    DispositivosNormais d1,d2;
    RadioCognitivo r1;
    r1 = new RadioCognitivo(ar1, 0, 50);
    r1.transmitir(ar1);
    d1 = new DispositivosNormais(0, 5);
    d1.transmitir(ar1);
    d2 = new DispositivosNormais(5, 7);
    d2.transmitir(ar1);    
    //System.out.println(ar1.conFreq(20) + "  " + d2.getFreq() + "  " + r1.getFreq());

    System.exit(0);
  }
  
}

acontece que eu gostaria de rodar concorrentemente os seguintes trechos do codigo:

r1 = new RadioCognitivo(ar1, 0, 50);
    r1.transmitir(ar1);

em uma thread t1, e:

d1 = new DispositivosNormais(0, 5);
    d1.transmitir(ar1);

em outra thread t2, e:

d2 = new DispositivosNormais(5, 7); d2.transmitir(ar1);
em outra thread t3.

Minha pergunta é da pra fazer isso com thread? e se sim, como eu posso fazer isso? Já tentei usar threads mas não consigo passar o metodo transmitir(arg) de jeito nenhum. Até pensei em usar o método run() passando argumentos nele, mas parece que isso não é possível. Enfim alguém poderia me dar uma help?

obrigado

4 Respostas

ViniGodoy
package br.com.rad.radiocog;

import java.util.ArrayList;

public class Estudos2{
  public static void main(String[] args) throws InterruptedException{
    final Ar ar1 = new Ar();    
    final DispositivosNormais d1 = new DispositivosNormais(0, 5);
    final DispositivosNormais d2 = new DispositivosNormais(5, 7);
    final RadioCognitivor1 = new RadioCognitivo(ar1, 0, 50);
    new Thread(new Runnable() {
        @Override
        public void run() {
            r1.transmitir(ar1);
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            d1.transmitir(ar1);
        }
    }).start();

    new Thread(new Runnable() {
        @Override
        public void run() {
            d2.transmitir(ar1);    
        }
    }).start();
  }  
}
sk2ck

Muito grato ViniGodoy. Aparentemente as threads estão preparadas para rodar paralelamente.

mas agora eu estou com outro problema. O codigo ficou assim:

package br.com.rad.radiocog;

import java.util.ArrayList;

public class Estudos2{
  public static void main(String[] args) throws InterruptedException{
    final Ar ar1 = new Ar();
    final DispositivosNormais d1 = new DispositivosNormais(0, 5); 
    final DispositivosNormais d2 = new DispositivosNormais(5, 7);
    final RadioCognitivo r1 = new RadioCognitivo(ar1, 0, 50);
    
    new Thread(new Runnable()
    {
    	public void run()
    	{
    		try {
    			System.out.println("thread1");
				r1.transmitir(ar1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	
    }).start();
    
    new Thread(new Runnable()
    {
    	public void run()
    	{
    		try {
    			System.out.println("thread2");
				d1.transmitir(ar1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	
    }).start();
    
    new Thread(new Runnable()
    {
    	public void run()
    	{
    		try {
    			System.out.println("thread3");
				d2.transmitir(ar1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	
    }).start();    

    System.exit(0);
  }
  
}

E quando eu mando executar, o resultado é os prints:

thread1
thread2

e não executa o thread3. Eu fiquei pensando que pode ser problemas de sincronização, já que o Objeto Ar ar1 é compartilhado entre as threads. Então eu distribui synchronized em todos os metodos que estou usando até agora. E imagina só! Nada, continua executando somente a 1 e 2 thread. Mas na verdade o que esta acontecendo é que o programa termina assim que printa thread1 e thread2. Então fico sem saber se a thread3 poderia ser executada ainda. Sinceramente não sei onde esta o problema… tens alguma idéia do que estou fazendo de errado?

obrigado

ViniGodoy

O código de threads é disparado em paralelo.
Portanto, assim que o método start() é executado, a nova thread começa a executar. Quem decide a ordem de execução (pois o paralelismo real é raro) é o sistema operacional.

Provavelmente seu código está atingindo o System.exit(0) antes que a thread3 tenha chance de executar pela primeira vez.

Esse comando mata o processo, eliminando todas as threads em execução.
Aliás, para que você colocou o System.exit ali?

Se você colocar um Thread.sleep(5000); antes do comando, para pausar a main thread por 5s, provavelmente verá as três threads executando.

ViniGodoy
Use o join() se quiser esperar uma thread parar de rodar.
package br.com.rad.radiocog;

import java.util.ArrayList;

public class Estudos2{
  public static void main(String[] args) throws InterruptedException{
    final Ar ar1 = new Ar();
    final DispositivosNormais d1 = new DispositivosNormais(0, 5); 
    final DispositivosNormais d2 = new DispositivosNormais(5, 7);
    final RadioCognitivo r1 = new RadioCognitivo(ar1, 0, 50);
    
    Thread thread1 = new Thread(new Runnable()
    {
    	public void run()
    	{
    		try {
    			System.out.println("thread1");
				r1.transmitir(ar1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	
    });
    
    Thread thread2 = new Thread(new Runnable()
    {
    	public void run()
    	{
    		try {
    			System.out.println("thread2");
				d1.transmitir(ar1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	
    });
    
    Thread thread3 = new Thread(new Runnable()
    {
    	public void run()
    	{
    		try {
    			System.out.println("thread3");
				d2.transmitir(ar1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	
    });    

    //Dispara as tres threads juntas
    thread1.start();
    thread2.start();
    thread3.start();
    //Espera elas terminarem
    thread1.join();
    thread2.join();
    thread3.join();

    //Só depois roda o exit.
    System.exit(0);
  } 
}
Criado 27 de outubro de 2011
Ultima resposta 30 de out. de 2011
Respostas 4
Participantes 2