|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Feb 2005
Messaggi: 295
|
[JAVA] sincronizzare thread
Ciao, sto facendo un esercizio sulla sincronizzazione dei threads in ambiente java...praticamente la situazione è questa: ho un server che gestisce l'arrivo di più thread; lo scopo dell'esercizio è quello di simulare la vendita di biglietti di un locale. Io nel thread avviato dal client arrivato c'è una chiamata ad un metodo statico, la chiamata al metodo avviene nel metodo run() del thread, che non fa altro che sottrarre il num di biglietti disponibili con il num di biglietti richiesti dal client...a questo punto dovrei gestire la sincronizzazione tra i thread..dovrei fare in modo che i thread eseguono questa sottrazione senza letture "sbagliate" cioè devo visualizzare il num di posti disponibili corretto...io ho scritto il metodo che effettua la sottrazione come synchronized ma solo questo non credo che basta. Non so se e dove andare ad inserire i metodi wait() e notify().
Questa è una parte del codice: //all'interno del metodo run() del thread richiestaClient = fromClient.readLine(); ServerLocale.Posti(richiestaClient); ToClient.writeBytes("prenotazione effettuata"); ... //il metodo Posti si trova all'interno della classe principale...quella che gestisce l'arrivo dei thread static int posti = 100; synchronized static int Posti(String richiestaCliente){ posti = posti - Integer.parseInt(richiestaCliente); return posti; } Ultima modifica di pumppkin : 17-04-2008 alle 18:32. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2773
|
Dov'è che visualizzi il numero di posti disponibili? Come mai non credi che basti?
|
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: Feb 2005
Messaggi: 295
|
in effetti provando senza wait() e notify() funziona senza problemi...però stavo pensando una cosa...secondo te se due thread prenotano contemporaneamente i biglietti non si verifica nessun problema di lettura?...scusa ma sono alle prime armi con la programmazione concorrente...
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Non vorrei dire una "fregnaccia" ma:
se la variabile statica che tiene traccia del numero di biglietti, il metodo che scrive sulla variabile e il metodo che legge la variabile stessero tutti e tre dentro la stessa classe e fossero synchronized allora appena uno di questi due metodi venisse invocato da un thread, quel thread otterrebbe il lock sull'istanza della classe, di fatto bloccando tutti gli altri eventuali thread, sia in lettura (tramite il metodo apposito) che in scrittura. ... Azz da qualche parte avevo una guida molto ben fatta e chiara circa il threading in Java, se la trovo te la posto. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Il metodo synchronized a quello serve: ad accodare eventuali chiamate multiple garantendo l' accesso univoco alla risorsa! Piu' che altro ormai tale meccanismo di mutua esclusione con la versione 6 di java è abbandonato in favore del meccanismo di lock().
In pratica basta racchiudere le istruzioni della sezione critica tra le istruzioni lock.lock(); .............................. ............................. lock.unlock(); ovviamente lock è una variabile della classe Lock inizializzata dinamicamente ad una sua realizzazione concreta. Detto questo non si capisce bene come tu effettui la prenotazione......il meccanismo deve funzionare pressochè cosi: -ogni thread conosce il Server di prenotazione -il server esporta i metodi di prenotazione che per forza di cose devono essere bloccati in mutua esclusione -ogni thread effettua le chiamate di prenotazione sul server Il thread deve credere di essere da solo ,mentre apunto il server deve preoccuparsi della giusta sincronizzazione degli accessi. Inoltre non ha molto senso utilizzare variabili e metodi statici in questo caso.Il server dovrebbe presumibilmente essere in unica istanza.Da considerare anche l' utilizzo di variabili statiche potrebbe essere pericoloso ai fini della sincronizzazione anche se hai ben evitato questo problema con static synchronized. Ultima modifica di nuovoUtente86 : 18-04-2008 alle 10:03. |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: May 2007
Messaggi: 526
|
ma potrebbe fare una cosa del genere:
//il metodo Posti si trova all'interno della classe principale...quella che gestisce l'arrivo dei thread static int posti = 100; synchronized static int Posti(String richiestaCliente){ if (posti<richiestaCliente) try ....wait(); posti = posti - Integer.parseInt(richiestaCliente); return posti; notifyall(); } |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
Inoltre per il tipo di situazione cui si attende fintanto che una certa condizione è vera esiste l' apposito strumento delle Condition utilizzato insieme appunto ai lock. Ultima modifica di nuovoUtente86 : 18-04-2008 alle 13:18. |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
ovviamente la condition va protetta da un ciclo while che verifichi che il thread risvegliato o corrente abbia il diritto di eseguire le istruzioni del metodo.Si avrà qualcosa del genere
while(condizione non verificato) condition.await(); ........................ ........................ .......................istruzioni signal()/signalAll(); |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: May 2007
Messaggi: 526
|
Quote:
se i biglietti finiscono....sò finiti. ho scritto solo un estratto di codice,per indicargli che se la risorsa è KO allora si ha wait/errore/...,mentre altrimenti "consuma" e notifica/segnala agli altri che ha consumato. |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
ma nel caso specifico dei biglietti l' unica coda è quella sul lock esplicito o implicito che sia e viene risvegliata all' unlock in caso e all' uscita dal metodo sincronizzato nell' altro!Ovviamente in altri contesti bisogna attendere ficnhe non si ha il diritto di eseguire e logicamente si usano i vari wait(),condition ecc
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: May 2007
Messaggi: 526
|
si,certo.
a stò punto,potrebbe crearsi un nuovo Monitor,che ha la sola signal,senza wait,e che realizza la signal con dei semafori binari a coda,richiamando i metodi p() e v(). e quindi usa stò monitor. elaboriosa,ma efficace. |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
gia funziona con syncronized o al limite con i lock.Perchè complicarsi la vita? |
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: May 2007
Messaggi: 526
|
appunto.
per questo ho detto che è elaboriosa. ![]() |
![]() |
![]() |
![]() |
#14 |
Member
Iscritto dal: Feb 2005
Messaggi: 295
|
intanto grazie di tutte queste risposte e proposte....comunque alla fine come avevo detto prima il problema si è risolto con il solo synchronized...inoltre dopo l'ho fatto anche con wait() e notifyAll()...so che potrebbero anche non servire tutte queste cose però l'esercizio richiedeva di sincronizzare i threads...quindi...penso che vada bene così...grazie
|
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
|
|
![]() |
![]() |
![]() |
#16 |
Member
Iscritto dal: Feb 2005
Messaggi: 295
|
penso di non aver commesso errori nell'utilizzo wait() e notifyAll()...praticamente ho creato due nuovi metodi lockwriting e unlockwriting...all'interno del metodo run() del thread ogni client, prima di andare a modificare la variabile che tiene conto dei posti del locale, richiama il metodo lockwriting ponendo la variabile booleana writing a true inoltre se writing è già a true allora un thread va in wait...una volta modificata la variabile viene richiamato il metodo unlockwriting dove viene posta la writing a false e viene chiamato il notifyAll...in questo modo chi era in wait può andare ad occupare la risorsa...
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
|
|
![]() |
![]() |
![]() |
#18 |
Member
Iscritto dal: Feb 2005
Messaggi: 295
|
fai conto che anche i metodi lockwriting e unlockwriting sono synchronized...più che altro ho seguito una guida che ho trovato in rete...comunque tutto questo lo so che è abbastanza inutile, infatti avevo già scritto sopra che funzionava tutto anche con il solo synchronized, solo che per ora mi serve per esercitarmi o comunque capire in che modo posso fare la sincronizzazione tra i threads....
questa è la guida che, più o meno, ho seguito: link Ultima modifica di pumppkin : 19-04-2008 alle 10:23. |
![]() |
![]() |
![]() |
#19 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Come vedi l' esempio del link è quello classico dei lettori/scrittori dove l' utilizzo del wait() ha senso per consentire ai lettori di accedere contestualmente alla risorsa qualora nessuno la sta modificando.Nel tuo caso tutti i thread sono paritari.
Questo meccanismo ora è offerto dal linguaggio tramite la concretizzazione ReadWriteLock della superclasse Lock. Ultima modifica di nuovoUtente86 : 19-04-2008 alle 11:04. |
![]() |
![]() |
![]() |
#20 |
Member
Iscritto dal: Feb 2005
Messaggi: 295
|
si ok hai ragione sul fatto che lì ha più senso...cmq come ti ho detto ho fatto solo una prova per vedere comunque se il programma girava senza problemi...adesso l'ho rimesso solo con il synchronized...cmq è strano che il prof non ha parlato della classe lock...ha parlato solo di wait notify, sleep, dei semafori, join...
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 03:08.