Pausar thread em execução

Galera, seguinte:

Vour rodar até 4 threads por vez. Cada uma podera ficar no ar até 10 segundos. Caso passe 10 segundos e elas não terminaram ela devera ser pausada e jogada para o final da minha fila.
A minha duvida é que não to sabendo fazer isso. Como vou pausar minha thread que esta em execução após X segundos ?

Sendo que de uma classe eu chamo a minha thread e dou o start() nela
Dentro da propria thread eu nao tenho wait, so de quem chamou ela correto ? No caso da classe onde eu dei o start() posso dar wait.
Acho que vou ter que criar um Timer na classe que chama ela e depois de x segundos parar a execução o problema é controlar 4 threads paara isso, nao sei to meio perdido …

Aceito dicas, sugestões, codigos hehe :slight_smile:

Valeu galera

Cara não entendi muito bem, mas vou tentar ajudar.

Acho que esse comportamento de para o processamento da thread em 10 segundos não é garantido. Vc pode tentar mas não tem garantia que vá dar certo.
Cara eu acho que vc vai ter que usar Time e TimeTask. Dá uma olhada nesse link http://www.dsc.ufcg.edu.br/~jacques/cursos/map/html/threads/timer.html

Tu pode criar um thread dentro de um TimeTask e depois de alguns segundos dar um yield no thread. É uma solução meio complicada e tenho quase certeza que não é um comportamento garantido.

Valeu

Se você explicar melhor qual o seu problema (porque você só pode usar quatro e porque elas devem voltar ao fim da fila após 10 segundos) fica mais fácil de vir com uma solução.

E ai pessoal beleza :slight_smile: Valeu pelos posts …

É mais ou menos o seguinte, errei. Na verdade eu inicio até 4 threads por que está especificado isso no documento onde tenho que fazer.
Cada thread pode ter várias instruções a executar, a cada duas instruções é para eu parar essa thread e dar chance a outra thread a executar suas 2 instruções e assim por diante e cada uma que terminar da espaço para uma outra thread dar o start. Essas outras threads estarão em uma List esperando a execução.

É isso :slight_smile:

[]´s

É o seguinte: Você pode usar o método sleep(tempo em milisegundos) da classe Thread. Você executa as duas intruções da thread e bota ela para dormir. O problema vai ser organizar a fila, tive um problema parecido e resolvi da seguinte forma:

Declarei um atributo estatico na classe que estende a classe Thread para funcionar como um contador, e a cada objeto novo criado ele vai receber uma “id” que vai servir para comparar como o contador. Você faz essa comparação dentro de um método synchonized, exemplo: void MetodoComparacao(), assim você só vai executar a thread que estiver na vez, caso contrario bota ela para dormir. Só não esqueça de garantir que o contador vai voltar ao inicio depois da ultima thread ser executada, senão não vai ter o efeito de uma fila circular.

Opa, blz ? Valeu pelo post … olha entendi bem sua idéia, mas aind ame ficaram dúvidas.

Tudo bem declaro lá por exemplo:

private static final int contador = 0;

Agora só não entendi uma coisa, e agora ? Cada vez que eu entrar no meu método run() eu seto o que nela ? Incremento ? Mas a toda hora entram processos e outros terminam, enfim … saquei o que vc quer dizer, mas aind anão abstrai para colocar em pratica hehehe :slight_smile:

Rola uma segunda explicação mais detalhada :slight_smile:

Abraços

Obs.: VOu postar uma parte da classe so pra ficar melhor:


...

private static final int contador = 0;

...

	public void executa() throws InterruptedException {		
		SysUtil sysUtil = new SysUtil();
		Cpu simulator = new Cpu();
		List operacoes = new ArrayList();
		try {
			operacoes = sysUtil.leArquivo(nomeArquivo);
		} catch (Exception e) {			
			e.printStackTrace();
		}
		
		for(int i = 0 ; i < operacoes.size() ; i++ ) {			
			Processo processo =  (Processo)operacoes.get(i);
			if( !processo.getInstrucao().equals(new Integer(12)) ) {
				acc = simulator.Simulacao( processo.getInstrucao().intValue() , acc , Double.valueOf(( ((Processo)operacoes.get(processo.getPosicao().intValue())).getInstrucao().toString()) ).doubleValue() );
				pc++;
			}
			else				
				break;			
		}		
	}

	public void run() {		
		try {
			executa();
		} catch (InterruptedException e) {			
			e.printStackTrace();
		}
		
	}


...
public class Exemplo extends Thread
{
    private static int contador = 1;
    private static int numero_threads = 0;
    private int id_thread;
    
    public Exemplo()
    {
        id_thread = GetID();         
    }
    
    public synchronized int GetID()
    {
        numero_threads++;
        return numero_threads;    
    }
    
    public void run() 
    {		
        try 
        {
                executa();
        }
        catch (InterruptedException e) {			
                e.printStackTrace();
        }
 		
    }
    
    public synchronized void executa()throws InterruptedException
    {
        if(id_thread == contador)
        {            
            /*
             Executa as instruções da thread corrente
            */    
             contador++;

        }        
        else
        {
            Thread.sleep(500);//coloca a thread corrente para dormir;        
        }
        
        if(id_thread == numero_threads)
            contador = 1; //reinicia o contador   
    
    }
}

Bem acho que isso explica tudo.
Cada objeto da classe Exemplo vai ter um id diferente.
Sera comparado com o contador, será ou não executado,
assim você vai ter controle das threads.

Exemplo ex1 = new Exemplo();

Esse objeto vai ter o id = 1, entao ele só vai ser executado quando o contador for igual a 1 no metodo executa.

Exemplo ex1 = new Exemplo();
Exemplo ex2 = new Exemplo();
Exemplo ex3 = new Exemplo();

Se existissem tres threads seus ids seriam respectivamente 1 , 2 e 3.
e só seriam executados nessa ordem.

Quando voce declara um metodo como synchronized,
apenas uma thread por vez poderá entrar no método.

Quando voce declara um atributo como static,
todos os objetos da classe vão ler e escrever em uma mesma
area de memoria em se tratando desse atributo, ou seja, se
um objeto setar o valor do atributo para 10 , todos os outros objetos
vão ver 10 como valor do atributo e vice-versa.

Qualquer dúvida, eu tento explicar novamente.

Fala Dejava blz … show meu valeu pelo post.

Implementei na minha. A primeira vez é executada, mas as demais ficam em pausa, sleep, nao sei aonde to errando ali. Vou postar o codigo da classe que extend Threads.

Obs.
: O construtor que recebe dois Integer não é usado para rodar a thread ( Start ) so chamo ele passando uns parametros, faço uns calculos e largo em uma lista.
Somente após a instancia do new Processo() que eu largo o start(). Por isso nao coloquei nada de codigo sobre seta id de thread ali.

package so;
import java.util.ArrayList;
import java.util.List;

import util.SysUtil;

/**
 * Classe uqe contém os processos que estão rodando
 *
 */
public class Processo implements Runnable  {
	
	private Integer instrucao; //Armazena a instrução que será executada
	private Integer posicao; //Armazena uma posição de memória
	private String nomeArquivo; //Nome do arquivo que sera lido
	private double acc; //Armazena nosso acumulador
	private int pc ;//Armazena o número de instruções que são executadas
	
	private static int contador = 1;
    private static int numero_threads = 0;
    private int id_thread;
	
	/**
	 * Construtoir da Classe Processo que recebe uma instrução e uma operação
	 * @param instrucao
	 * @param posicao
	 */
	public Processo(Integer instrucao , Integer posicao){
		this.instrucao = instrucao;
		this.posicao = posicao;		 
	}
	
	
	/**
	 * Construtor default da classe
	 *
	 */
	public Processo(){	
		id_thread = GetID(); 
	}
	
	 public synchronized int GetID()
     {
         numero_threads++;
         return numero_threads;    
     }
	
  
	
	/**
	 *  Método que é chamado ao iniciar um processo retirado da memoria.
	 * @throws InterruptedException
	 */
	 synchronized void executa() throws InterruptedException {
		 
		if(id_thread == contador)  { 	 
			SysUtil sysUtil = new SysUtil(); //Classe Utils
			Cpu simulator = new Cpu(); //Nossa CPU que será responsável pelos cálculos
			List operacoes = new ArrayList(); //Operações do processo
			try {
				//Armazena as operações lidas do arquivo
				operacoes = sysUtil.leArquivo(nomeArquivo);
			} catch (Exception e) {			
				e.printStackTrace();
			}
			
			//Percorre o numero de operações disponíveis aramzenando em uma Lista
			// que será usada depois
			for(int i = 0 ; i < operacoes.size() ; i++ ) {
				//Cria um processo
				Processo processo =  (Processo)operacoes.get(i);
				//Se for a instrução 12 termina. Se não for segue calculos.
				if( !processo.getInstrucao().equals(new Integer(12)) ) {
					acc = simulator.Simulacao( processo.getInstrucao().intValue() , acc , Double.valueOf(( ((Processo)operacoes.get(processo.getPosicao().intValue())).getInstrucao().toString()) ).doubleValue() );
					pc++;
				}
				else				
					break;			
			}
			contador++;
		}
		else  {
            Thread.sleep(500);//coloca a thread corrente para dormir;        
        }		
		
		if(id_thread == numero_threads)
            contador = 1; //reinicia o contador 
	}

	public void run() {		
		try {
			//Chama o método executa
			executa();
		} catch (InterruptedException e) {			
			e.printStackTrace();
		}
		
	}
	
	 /**
	* Get e Set	  
    */	
	public Integer getInstrucao() {
		return instrucao;
	}
	public void setInstrucao(Integer instrucao) {
		this.instrucao = instrucao;
	}
	public double getAcc() {
		return acc;
	}

	public void setAcc(double acc) {
		this.acc = acc;
	}
	public int getPc() {
		return pc;
	}

	public void setPc(int pc) {
		this.pc = pc;
	}

	public Integer getPosicao() {
		return posicao;
	}
	public void setPosicao(Integer posicao) {
		this.posicao = posicao;
	}
	public String getNomeArquivo() {
		return nomeArquivo;
	}

	public void setNomeArquivo(String nomeArquivo) {
		this.nomeArquivo = nomeArquivo;
	}


}