PDA

View Full Version : Multi Threading + Servlet


StefanoCsl
19-01-2004, 10:41
Ciao a tutti,
vorrei sapere come si devono gestire i multi threading nelle servlet Java.
Grazie 1000
Stefano

kingv
19-01-2004, 11:14
devi evitare di utilizzare all'interno della servlet dei membri della classe che potrebbero essere accedute da thread diversi contemporaneamente.
Ti faccio un esempio su cosa NON devi fare:

public class Example extends HttpServlet
{
HttpSession session;

public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
session = request.getSession();
//ecc.ecc.
}
}

il codice scritto sopra e' MOLTO pericoloso perche' nulla impedisce al servlet engine di utilizzare la stessa istanza della servlet per soddifare due differenti richieste. Il rischio e' in questo caso di soddifare una richiesta usando l'oggetto session che e' stato creato per un altra :eek:, con conseguente "scambio" di sessione...

lombardp
19-01-2004, 11:25
Originariamente inviato da kingv
devi evitare di utilizzare all'interno della servlet dei membri della classe che potrebbero essere accedute da thread diversi contemporaneamente.
Ti faccio un esempio su cosa NON devi fare:


E' un argomento abbastanza "spinoso", su cui non ho ancora trovato risposte certe.

Qual'è il modo corretto di fare qualcosa di analogo a quello che hai scritto?

kingv
19-01-2004, 11:57
Originariamente inviato da lombardp
E' un argomento abbastanza "spinoso", su cui non ho ancora trovato risposte certe.

Qual'è il modo corretto di fare qualcosa di analogo a quello che hai scritto?


la maniera corretta e' quella di utilizzare solo variabili locali ai metodi.
Nel caso debba passare un oggetto da un metodo all'altro devi passarlo come parametro a un metodo e non accedere a un membro della classe (ad esempio un metodo nell'esempio precedente che necessita dell'oggetto Session dovrebbe prevederlo tra i parametri con cui viene richiamato). So benissimo che a livello di design e' una limitazione notevole, ma se si vogliono scrivere servlet che possano essere deployate senza remore su application server diversi e' l'unica maniera di scriverle. L'alternativa (sugli application che lo consentono) e di implementare l'interfaccia SingleThreadModel e utilizzare il pooling delle servlet a livello di container (e' per questo che ho detto: se l'application lo consente).
So che le specifiche sarebbero dovute cambiare con gli ultimi rilasci (2.4) ma non ho avuto il tempo di leggere niente, anche perche' sto lavorando su altre tecnologie in questo momento..

kingv
19-01-2004, 12:00
mi sono letto le specifiche delle servlet 2.4, non e' cambiato nulla rispetto a cio' che ho scritto sopra a parte che l'utilizzo di SingleThreadModel e' stato deprecato (ed e' quindi sconsigliato).

lombardp
19-01-2004, 12:59
Dimmi se ho capito bene: se faccio una servlet, al cui interno ho un oggetto SESSIONE, e due utilizzatori diversi accedono all'oggetto SESSIONE della servlet, possono crearsi dei problemi.

Tutto questo a prescindere dal fatto che la "sessione" è (dovrebbe essere) unica per ogni utilizzatore? Oppure il problema consiste nel fatto che la "sessione" viene memorizzata in una variabile membro della servlet? In tal caso vale esattamente anche per le pagine JSP, giusto?

kingv
19-01-2004, 14:12
Originariamente inviato da lombardp
Dimmi se ho capito bene: se faccio una servlet, al cui interno ho un oggetto SESSIONE, e due utilizzatori diversi accedono all'oggetto SESSIONE della servlet, possono crearsi dei problemi.

Tutto questo a prescindere dal fatto che la "sessione" è (dovrebbe essere) unica per ogni utilizzatore? Oppure il problema consiste nel fatto che la "sessione" viene memorizzata in una variabile membro della servlet? In tal caso vale esattamente anche per le pagine JSP, giusto?



ho fatto un esempio con un oggetto di classe Session perche' e' un caso tipico, ma naturalmente vale per qualsiasi oggetto membro della classe (servlet).

non sono un esperto di JSP ma se non ricordo male gli oggetti che dichiari con scope "page" sono tradotti in servlet in cui sono comunque locali al metodo service().
Se hai voglia/tempo puoi fare una prova e verificare il codice della servlet generata per rendertene conto, quando ho un attimo magari lo faccio io ;)