SingleThreadModel no Tomcat

4 respostas
M

Bom dia,

Tenho uma funcionalidade na minha aplicação que tem um tempo de processamento bastante demorado.

Se estiver sendo executado, e um outro usuário executar ao mesmo tempo gera duplicidade da base de dados.

Resolvi implementar a interface SingleThreadModel no meu servlet, mas não funcionou.

O artigo do GUJ “Thread Safety com Servlets”, diz que essa implementação funciona de maneira diferente de servidor para servidor.

Estou usando o tomcat 5.5.9, alguem sabe como funciona nessa versão do tomcat, ou se existe alguma outra forma de fazer com que esse servlet não permita execuções concorrêntes?

Grato,

Rodrigo.

4 Respostas

I

Não sei responder a tua pergunta. De qualquer forma porque não implementas um esquema de semáforo? Estais sincronizando a parte que é crítica e deixando os demais processos em espera?

public class MyTask extends Thread {
    public void run() {
         execute();
    }

    /* O primeiro que chegar aqui vai dar um lock no método. Os demais
     * entram em estado de espera e quando o processo estiver saindo ele
     * irá notificar todos em espera e o próximo será escalonado. Starvation
     * é uma condição a ser considerada, mas podes usar as classes
     * PriorityBlockingQueue, SynchronousQueue ou BlockingQueue para
     * gerenciar as prioridades.
     */
    private void synchronized execute() {
        try {
         //doing something late...
        } finally {
            notifyAll();
        }
    }
}

//Dentro do teu servlet...
    Thread thread = new MyTask();
     thread.start();
//...

Na verdade no Java5 foi acrescentado a API para tarefas concorrentes,
java.util.concurrent.*

T+

M

Olá iktuz,

O que eu quero fazer é esse esquema de semáforo que você disse.
Mas não intendi esse código que você colocou.

Mais um detalhe, estou utilizando struts, dessa forma não posso herdar a classe Thread, uma vez que minha classe tem que herdar a classe DispatchAction.

Obrigado

G

Caso não conheça muito bem a programação concorrente em Java, dê uma lida: http://java.sun.com/docs/books/tutorial/essential/concurrency/

M

Consegui resolver meu problema.
Na verdade viz algo mais simple que não tinha pensado antes.

Utilizei uma variável estática para controlar se o método esta sendo executado, caso esteja em execução sai do método sem fazer nada.

public class MinhaClasse extends DispatchAction {

	private static boolean locked = false;
		
	public ActionForward MeuMetodo(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		if (locked) 
			mapping.findForward("Home");
		
		try {
			locked = true
			//Código
		}
		finally{
			locked = false
		}
	}
}

Obrigado a todos :grin:

Criado 1 de dezembro de 2006
Ultima resposta 1 de dez. de 2006
Respostas 4
Participantes 3