Java, Servlet e multithreading cosa fare

Luca Bartoli

Molto spesso si sente parlare di ciclo di vita delle Servlet e di multithreading. Per capire di cosa stiamo parlando vi mostro una esemplificazione del ciclo di vita di una servlet:

  1. Se non è ancora presente una istanza della servlet nel Web Context questa:
    1. Carica la classe della Servlet
    2. Crea un'istanza della servlet
    3. Inizializza l'istanza chiamando il metodo init
  2. Il Web Container invoca il metodo service (che è threddizzato) con la request e la response legata alla richiesta arrivata dal client.
  3. Quando la servlet non serve più (il WEB Container decide di rimuoverla) viene chiamato il metodo destroy.

Fondamentalmente ogni volta che arriva una richiesta da un client il container chiama, con un thread, il metodo service (che nelle HttpServlet invoca i doGet, doPost, doDestroy ecc.. a seconda del caso) passando request e respons e di conseguenza anche la session appropriata.

Da questo si deduce che la servlet in realtà è solo una all’interno del container e che quindi se noi volessimo scrivere un attributo di classe correremmo il rischio che tutti i thread che invocano service contemporaneamente andrebbero lo andrebbero ad usare interferendo l’una con l’altra.

Per fare un esempio concreto, si potrebbe immaginare una ervlet che all’interno del metodo service (doGet o doPost) faccia delle operazioni pesanti che impiegano anche un solo secondo a terminare, in questo caso se due utenti dovessero fare una richiesta nello stesso secondo e si dovesse utilizzare un attributo di clessa per memorizzare un parametro passato dal client, sicuramente il secondo chiamante andrebbe a sovrascrivere lo stato dell’attributo settato dal primo.

Per simulare una caso del genere sarà sufficiente inserire uno sleep, all’interno del metodo, per permettere di simulare due client che inviano una richiesta contemporaneamente.

Il codice della pagina html è:

e nel metodo doPost della servlet ServletMultithreading richiamata dalla form in post:

Ora chiamando due volte la pagina html e inviando il form, da due pagine diverse e con un intervallo massimo di 10 secondi, con il campo nome riempito con due distinti valori noteremo che il valore del nome restituito da entrambe le pagine sarà quello della form inviata per seconda.

Questo, come detto sopra, è dato dall’utilizzo del’attributo di calsse per memorizzare il parametro inviato dalla form.

Per evitare questo inconveniente si potrebbero cercare di utilizzare diverse soluzioni, una fra le diverse è quella di sincronizzare l’accesso all’attributo con

Con questo però in realtà si impedisce solo che lo stesso attributo venga scritto contemporanemente da due thread diversi, operazione che potrebbe generare un errore, ma non eliminerebbe il problema.

L’unico modo certo è quello di scrivere sempre gli attributi a livello di metodo e non di classe

Similar Posts:


Lascia un Commento