|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
[Java] concorrenza in servlet
Ciao a tutti.
Ho una action (o una servlet, poco cambia) che contiene una parte di codice in cui devo impedire l'esecuzione di più processi in contemporanea. Trattandosi di una servlet, viene creata un'istanza diversa per ogni utente che la esegue (non è singleton). Ho pensato di risolvere il problema in questo modo ma vorrei un vostro parere: ... public static final String LOCK_V = "lock_ccu"; public String execute() throws Exception { ... synchronized (LOCK_V) { //codice in concorrenza ... } ... } In pratica eseguendo il synchronized sulla variabile statica LOCK_V impedisco che istanze diverse della servlet eseguano contemporaneamente la porzione di codice compresa nel blocco. Questo perchè LOCK_V è variabile di classe. Che ne dite? Non sto considerando qualcosa? Ultima modifica di Swalke : 13-07-2008 alle 13:00. |
![]() |
![]() |
![]() |
#2 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
UP.
Nessuno mi dice nulla? ![]() |
![]() |
![]() |
![]() |
#3 | ||
Member
Iscritto dal: Nov 2003
Messaggi: 40
|
Quote:
Quote:
che genere di risorsa devi gestire per gli accessi concorrenti? ti faccio un esempio: se hai un attributo del ServletContext e devi fare in modo che le diverse servlet vi accedano in maniera concorrente, ti basta costruirti un blocco synchronized che usa come mutex il ServletContext ogni volta che si accede a quello specifico attibuto. |
||
![]() |
![]() |
![]() |
#4 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
In pratica la porzione di metodo che volevo sincronizzare esegue un accesso al database ed estrae il valore di una variabile. In base al suo valore la aggiorna e crea un file con il nome di questa variabile.
In pseudoicodice ciò che deve essere sincronizzato è qualcosa di simile a questo: Codice:
variabile=lettura variabile da DB; if(variavile='a') { salvataggio file "a.txt"; variabile = 'b'; } if(variavile='b') { salvataggio file "b.txt"; variabile = 'c'; } if(variavile='c') { salvataggio file "c.txt"; variabile = 'd'; } ... update variabile su db; Se il thread 1 ha letto da db il valore 'a', io voglio che finisca di operare prima che un thread 2 concorrente legga la variabile da db. Pensavo di avere risolto il problema. Secondo te come posso risolvere? |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9446
|
Quindi il tuo problema, se non sbaglio, e' quello di accedere in maniera concorrente al db ?
In tal caso penso tu possa "semplicemente" utilizzare un livello di isolamento appropriato al tuo caso, per evitare che i thread relativi alle varie richieste possano incorrere in "corse critiche". P.S.: per quanto riguarda il "modello" dei servlet... non dovrebbe essere invocato il metodo init nel momento in cui viene caricata l'applicazione dal servlet engine ed essere, poi, creato un thread per ogni richiesta (GET o POST) ricevuta ?
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
![]() |
![]() |
![]() |
#6 | ||
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
Quote:
Il fatto è che a me sembra di essermi tutelato in modo corretto sincronizzando quel blocco di codice. I thread della servlet dovrebbero accedere in modo sincronizzato a quel blocco come mi pare di capire da qui: http://java.sun.com/docs/books/tutor.../locksync.html. Quindi non ho ben capito cosa intende smodeus quando dice Quote:
|
||
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Jan 2004
Città: Montignoso(MS)
Messaggi: 9446
|
Se la variabile e' statica e' condivisa da tutti i thread che vengono creati per cui credo che il synchronized possa essere utilizzato con "successo".
Imho, pero', visto che il problema e' relativo all'accesso al db prenderei in considerazioni di utilizzare in maniera "piu' pulita" i livelli di isolamento del db in questione.
__________________
"Il Meglio che si possa ottenere è evitare il peggio." I.C. |
![]() |
![]() |
![]() |
#8 |
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
ma se l'accesso al db avviene in blocco che ho sincronizzato perchè dovrei avere problemi?
|
![]() |
![]() |
![]() |
#9 | ||
Member
Iscritto dal: Nov 2003
Messaggi: 40
|
Quote:
E' questo metodo che decide quale dei metodi doXXX (doGet, doPost, etc) eseguire Quindi init() (entrambi gli overload) vengono invocati 1 sola volta nel ciclo di vita della servlet, mentre service() viene invocato ogni volta c'è una nuova richiesta Quote:
public static final String LOCK_V = "lock_ccu"; public String execute() throws Exception { ... synchronized (LOCK_V) { //codice in concorrenza ... } ... } Ma è una sola servlet che accede a questo dato? In questo caso la soluzione va bene, se invece sono + servlet, allora questa soluzione non va bene, perchè nn ti garantisce l'accesso sincrono da parte di diverse servlet, che rappresentano classi diverse. In generale cmq cercherei di non introdurre blocchi syncrhonized nelle servlet, ovviamente poi dipende anche dai "carichi" che potresti avere su quella servlet (quanti client posso contemporaneamente richiedere quella servlet) |
||
![]() |
![]() |
![]() |
#10 | ||
Member
Iscritto dal: Dec 2004
Messaggi: 131
|
Quote:
In realtà ho commesso un errore e chiedo perdono: il metodo che ho chiamato "execute" nel mio esempio è in realtà un doGet o un doPost. Dunque l'intestazione del mio metodo di esempio sarebbe la classica public void doGet(HttpServletRequest request, HttpServletResponse response)... Quindi il blocco sincronizzato è all'interno del metodo della servlet che risponde alla richiesta. Dunque la mia sincronizzazione è corretta vero? Quote:
Ultima modifica di Swalke : 14-07-2008 alle 14:19. |
||
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:39.