Thread em Java

8 respostas
P

Bom antes de mais nada pesquisei sobre assunto no fórum e não encontrei nada que resolvesse meu problema, a questão é a seguinte.

Tenho um código em java Cliente/Servidor, para enviar arquivos via socket, o código funciona perfeitamente, mais o que eu de fato queria é o seguinte:
O servidor cria uma thread para receber uma conexão e outra para enviar um arquivo, porém o que eu percebi é que o código trava os botões da tela se eu por para enviar um arquivo muito grande os botões das telas ficam bloqueados enquanto os arquivos são transferidos, o grande problema é este, por que isso ocorre, já que a comunicação é feita por thread que opera de forma independente, da “Thread Pai”.

Se for necessário posto o código da aplicação sem problemas.

8 Respostas

S

Quando vc envia um arquivo muito grande, ele vai terminar de enviar para voltar o controle para o seu programa, no caso eu recomendo que você divida este seu arquivo em partes e entre
os pedaços enviados vc dê o sleep na thread.

P

A questão é que o servidor tbm fica parado, o que não faz sentido se estou usando thread, é para ter execução paralela(leia se concorrente), pois se eu tiver varios clientes conectados ao servidor somente um iria conseguir enviar o arquivo. O que ocorre é uma ação blocante tanto do cliente quanto do servidor e no caso isso não era para ocorrer, pois chamo a thread com start() e não join, o que cria as conexões tbm é uma thread.

EduFrazao

Amigo, explique melhor seu ambiente. Nem consegui figurar se você tem uma app em desktop, que envia arquivos para um servidor que redistribui a informação, ou se é uma APP Web, enviando um arquivo e o servidor fazendo upload em outro lugar (onde não faria sentido lockar a UI).

Se você está usando uma APP Desktop, é natural lockar a UI no caso de uma operação deste tipo, pois os eventos disparados pela UI rodam na Thread de renderização, e você começou bem startando uma nova thread para cuidar deste trabalho específico. Por favor, poste um trecho de código.

L

A melhor forma de executar tarefas sem bloquear a interface é executar de forma assíncrona.

Ajudaria saber qual o ambiente de trabalho, no Android por exemplo, temos a classe AssyncTask pra tratar manipular essas situações.

C

Provavelmente você está criando threads manualmente quando swing oferece maneiras próprias pra executar tarefas de background, como enviar arquivos via socket, sem travar a UI.

Faz tempo que não uso Swing, mas se não me engano a classe que você procura se chama SwingWorker.

F

Paulo, estou curioso em saber porque vc tem uma thread pra receber a comunicação, e outra só pra mandar o arquivo… não poderia ser a mesma thread ? (sou novato, não estranhe se for besteira) …

Aproveito a expor a seguinte questão, e tentar resoover a dúvida de qual melhor gerenciamento de conexão entre servidor/ cliente.
Segue a situação:
Um servidor, via fluxo socket se comunica com vários tablets (uns 20).

  • devo iniciar uma thread para cada conexão, e esta ficar ativa o tempo todo para este tablet (mesmo que nem sempre há diálogo) ? ; ou
  • devo iniciar uma thread toda vez que houver comunicação a fazer entre o tablet e o servidor, e findando a comunicação, finalizar a thread ?; ou
  • devo iniciar uma thread pra cada conexão, e por-la pra dormir mediante ausência de comunicação ?

em qual situação tenho melhor desempenho ?
existe outra maneira melhor ainda do que as mencionadas ?
e outra, como, dentro da própria thread, eu consigo encerrar-la ? (ou teria que usar um gerenciador de thread´s ?)

agradeço por antecipação … e desculpa se não estiver no tópico certo … (tento não gerar redundância de tópicos) …

B

Boa noite

Uso isto no android, para a tarefa ficar em background, neste caso é um login:

/*Neste exemplo eu estou autenticando um usuario novo, consulto um Web Service*/
	class LoginAsyncTask extends AsyncTask<String, Void, Boolean>{
		 private ProgressDialog progressDialog;  
		 private Exception erro; 
		 
		  protected void onPreExecute() {  
		    progressDialog = new ProgressDialog(LogarActivity.this);  
		    progressDialog.setMessage(getString(R.string.please_wait)); //mensagem do dialogo de progresso
                    
                    //se vc não quiser exibir a barra de progresso, então comente as 3 linhas abaixo    
                    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		    progressDialog.setProgress(0);
		    progressDialog.setMax(100);  
		    
                    progressDialog.show();  
		  }  
		
		@Override
		protected Boolean doInBackground(String... params) {
			
                       try{
                           
                          progressDialog.setProgress(10);    			
			/*
                             [....] Envio p/web service params[0] e params[1] que são respectivamente usuario e senha
                       */   
                       }catch(Exception e){
                                erro=e;
                               return false;
                       } finally{
                             progressDialog.setProgress(100);
                             //libera recursos tb, por exemplo fechar o sqlite após o uso
                       }
                      return true;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			//fecha progresso
			progressDialog.dismiss();
			
			if(result){
				startActivity(intent);
				finish();
			}else{
				Toast.makeText(LogarActivity.this,"Sem acesso ao sistema, motivo: "+erro.getMessage() , Toast.LENGTH_LONG).show();
				erro.printStackTrace();
				etSenha.setText("");
				etUsuario.setText("");
				etUsuario.setFocusable(true);
			}
		}
	}

Chamo assim no onClick do Button, exemplo:

new LoginAsyncTask().execute(new String[]{"system","123"});
jcranky

Se for uma aplicação desktop, dê uma olhada no SwingUtilities.invokeLater. Mas como mencionaram antes, está mesmo um pouco difícil de entender o seu cenário.

Criado 26 de maio de 2013
Ultima resposta 30 de mai. de 2013
Respostas 8
Participantes 8