Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Attendere la fine di un thread

192 views
Skip to first unread message

sergio

unread,
Dec 6, 2009, 12:08:09 PM12/6/09
to
Ragazzi,
mi sono incastrato in un problema sulla sincronizzazione dei thread.
Il mio obiettivo è attendere che un tread termini prima di continuare
con l'esecuzione di un metodo.

Di seguito vi descrivo a grandi linee come è strutturata
l'applicazione. Si tratta di un meccanismo per l'accesso ai dati.
Sostanzialmente una classe richiedente (A) invoca un metodo (execute
()) di un Singleton che estende Thread (da qui in poi DE) che, nel suo
metodo run(), è in costante attesa di nuove richieste. Una volta
ricevuta una nuova richeista (tramite l'invocazione del metodo sopra
citato), DE crea un nuovo processo (da qui DEP) che elabora la
richeista fatta da A.

Tanto per essere più chiaro di seguito riporto un estratto del metodo
execute() di DE
----------------------------------------------------------------
public synchronized String execute() {
DER req = new DER(context, qname, qparams);
requests.add(req);
this.notify();

DQ q = null;

//[!]: qui occorre ua sincronizzazione su DEP

DEP depThread = req.getDEP(); //recupera il processo che
gestisce la richeista [!]: ritorna null in quanto non sincronizzato
con run()
try {
depThread.join(); //attendi che il thread muoia [!]:
qui viene sollevata una NullPointerException
} catch (InterruptedException eDep) { //quando il thread
muore recupera i dati dell'esecuzione
q = depThread.getExecutionResult();
}

return (q == null) ? null : q.toString();
}

----------------------------------------------------------------

e un estratto del metodo run() di DE

try {
while (true) { //tieni attivo il processo
if (requests.isEmpty() || runningThread == maxThread)
try { //se non ci sono richieste pending oppure
se tutti i processi sono occupati
wait(); //sospendi il processo
} catch (InterruptedException e) {
//è arrivata nuova richiesta oppure si è
liberato quelhce processo
}

//se il processo è attivo...
try {
//avvia un processo per la gestione della
richiesta
DER der = requests.firstElement();
DEP dep = new DEP(der);
der.setDataEngineProcessor(dep);
dep.start();
} catch (Exception e) {
//Errore nell'istanziazione del processo per
l'elaborazione della richiesta
} finally {
//elimina la richiesta elaborata
requests.removeElementAt(0);
}
}
} finally {
///esecuzone del processo principale terminata
}
}

----------------------------------------------------------------
Il mio obiettivo è di sincronizzare il metodo execute() sull'oggetto
"der" in modo tale da recuperare il valore del processo DEP sse questo
è disponibile (cioè quando è stato settato da
"der.setDataEngineProcessor(dep);" nel metodo run() di DE).

Ho provato con i vari wait(), notify(), notifyall(), join(), e con i
blocchi/metodi "syncrhronized" ma se non surgelo tutta l'applicazione
ottengo una fastidiosa IllegalMonitorStateException.

Potreste gentilemnte darmi qualche dritta su come risolvere la
questione?
Grazie mille a tutti

TempestaT400

unread,
Dec 11, 2009, 6:49:50 PM12/11/09
to
Ciao Sergio...
Allora, IllegalMonitorStateException la ottieni quando cerci di invocare una
wait o una notify o qualsiasi altro metodo relativo alla sincronizzazione
senza aver acquisito il lock...
Se ho capito bene quello che devi fare, credo potresti risolvere il tutto
utilizzando due semafori evento!
Inizializzi un semaforo a zero

Semaphore s = new Semaphore(0);

....

execute(){
.....
....
s.acquire();
/*
il processo che acquisisce il semaforo senza posti disponibili viene
messo in coda... Questo viene risvegliato non appena si libera una
posizione...
questa posizione viene aggiunta mediante la chiamata della release sul
semaforo che avviene nel run...
� semplice sincronizzazione di processi mediante semafori... protesti
anche farlo mediante l'utilizzo di Condition...
(secondo me molto pi� indicate)..
*/
}

run(){
...
...
...
s.release();
}

Spero di esserti stato utile...
TempestaT400

sv

unread,
Dec 14, 2009, 6:07:21 AM12/14/09
to
sergio wrote:
> Ragazzi,
> mi sono incastrato in un problema sulla sincronizzazione dei thread.
> Il mio obiettivo � attendere che un tread termini prima di continuare

> con l'esecuzione di un metodo.
> [...]
> Il mio obiettivo � di sincronizzare il metodo execute() sull'oggetto

> "der" in modo tale da recuperare il valore del processo DEP sse questo
> � disponibile (cio� quando � stato settato da

> "der.setDataEngineProcessor(dep);" nel metodo run() di DE).
>
> Ho provato con i vari wait(), notify(), notifyall(), join(), e con i
> blocchi/metodi "syncrhronized" ma se non surgelo tutta l'applicazione
> ottengo una fastidiosa IllegalMonitorStateException.
>
> Potreste gentilemnte darmi qualche dritta su come risolvere la
> questione?
> Grazie mille a tutti

Creare un metodo callback nel thread che deve aspettare l'esecuzione?


--
sv.

sergio

unread,
Dec 15, 2009, 4:26:30 PM12/15/09
to
On 14 Dic, 12:07, sv <s...@sv.es> wrote:
> sergio wrote:
> > Ragazzi,
> > mi sono incastrato in un problema sulla sincronizzazione dei thread.
> > Il mio obiettivo è attendere che un tread termini prima di continuare

> > con l'esecuzione di un metodo.
> > [...]
> > Il mio obiettivo è di sincronizzare il metodo execute() sull'oggetto

> > "der" in modo tale da recuperare il valore del processo DEP sse questo
> > è disponibile (cioè quando è stato settato da

> > "der.setDataEngineProcessor(dep);" nel metodo run() di DE).
>
> > Ho provato con i vari wait(), notify(), notifyall(), join(), e con i
> > blocchi/metodi "syncrhronized" ma se non surgelo tutta l'applicazione
> > ottengo una fastidiosa IllegalMonitorStateException.
>
> > Potreste gentilemnte darmi qualche dritta su come risolvere la
> > questione?
> > Grazie mille a tutti
>
> Creare un metodo callback nel thread che deve aspettare l'esecuzione?
>
> --
> sv.- Nascondi testo citato
>
> - Mostra testo citato -

Callback nel senso di implementare una sorta di observer? Ci avevo
pensato solo che questo pattern in genere l'ho usato in situazioni
asincrone, quello che mi manca qui è invece proprio la
sincronizzazione tra i metodi.... ovviamente correggimi se ho detto
qualche stupidaggine :)

Ho provato la soluzione proposta da TempestaT400 e sembra che il
problema sia stato agevolmente risolto :). In ogni caso mi piacerebbe
avere anche qualche dettaglio in più riguardo la tua idea (magari
potrebbe tornare utile in futuro a me o a qualcun'altro lettore del
ng...). Potresti gentilmente indicare qualche altro dettaglio in
merito?

Grazie 1000 a tutti. Siete come sempre fondamentali ;)
Ciao
Sergio

sv

unread,
Dec 16, 2009, 3:10:00 AM12/16/09
to
sergio wrote:
> On 14 Dic, 12:07, sv <s...@sv.es> wrote:
> Callback nel senso di implementare una sorta di observer? Ci avevo
> pensato solo che questo pattern in genere l'ho usato in situazioni
> asincrone, quello che mi manca qui � invece proprio la

> sincronizzazione tra i metodi.... ovviamente correggimi se ho detto
> qualche stupidaggine :)
>
> Ho provato la soluzione proposta da TempestaT400 e sembra che il
> problema sia stato agevolmente risolto :). In ogni caso mi piacerebbe
> avere anche qualche dettaglio in pi� riguardo la tua idea (magari

> potrebbe tornare utile in futuro a me o a qualcun'altro lettore del
> ng...). Potresti gentilmente indicare qualche altro dettaglio in
> merito?
>
> Grazie 1000 a tutti. Siete come sempre fondamentali ;)
> Ciao
> Sergio


Se ho capito la tua situazione hai un thread che svolge un lavoro ed un
altro che invia i job da fare e deve attendere il risultato.

Quindi il thread che svolge la computazione potrebbe mettere il lavoro
eseguito in una coda (bloccante) mentre chi ha sottomesso il lavoro la
legge.

Il problema ti si generava perch� il metodo req.getDEP() non era
bloccante (cosa che in alcuni casi � utile), ussanto il callback, quando
il thread che svolge il lavoro ha terminato invoca sull'oggetto il
metodo callback (es. setWorkDone(Work w) ) che potrebbe banalmente
inserirlo in una coda.

Eventualmente prova a guardare java.util.concurrent.Future ed il Worker
Thread pattern.


--
sv.

sergio

unread,
Dec 18, 2009, 4:57:20 PM12/18/09
to
On 16 Dic, 09:10, sv <s...@sv.es> wrote:
> sergio wrote:
> > On 14 Dic, 12:07, sv <s...@sv.es> wrote:
> > Callback nel senso di implementare una sorta di observer? Ci avevo
> > pensato solo che questo pattern in genere l'ho usato in situazioni
> > asincrone, quello che mi manca qui è invece proprio la

> > sincronizzazione tra i metodi.... ovviamente correggimi se ho detto
> > qualche stupidaggine :)
>
> > Ho provato la soluzione proposta da TempestaT400 e sembra che il
> > problema sia stato agevolmente risolto :). In ogni caso mi piacerebbe
> > avere anche qualche dettaglio in più riguardo la tua idea (magari

> > potrebbe tornare utile in futuro a me o a qualcun'altro lettore del
> > ng...). Potresti gentilmente indicare qualche altro dettaglio in
> > merito?
>
> > Grazie 1000 a tutti. Siete come sempre fondamentali ;)
> > Ciao
> > Sergio
>
> Se ho capito la tua situazione hai un thread che svolge un lavoro ed un
> altro che invia i job da fare e deve attendere il risultato.
>
> Quindi il thread che svolge la computazione potrebbe mettere il lavoro
> eseguito in una coda (bloccante) mentre chi ha sottomesso il lavoro la
> legge.
>
> Il problema ti si generava perché il metodo req.getDEP() non era
> bloccante (cosa che in alcuni casi è utile), ussanto il callback, quando

> il thread che svolge il lavoro ha terminato invoca sull'oggetto il
> metodo callback (es. setWorkDone(Work w) ) che potrebbe banalmente
> inserirlo in una coda.
>
> Eventualmente prova a guardare java.util.concurrent.Future ed il Worker
> Thread pattern.
>
> --
> sv.- Nascondi testo citato
>
> - Mostra testo citato -

Grazie dei chiarimenti. Andrò subito a guardarmi i riferimenti che mi
hai indicato.
La questione dei thread e della concorrenza è una cosa che mi
interessa molto e che vorrei approfondire per riuscire a muovermi
agevolmente in questo ambito.

Un'altra domanda, immagino banale ma che contribuisce a chiarirmi
meglio i dubbi sulla sincronizzazione: supponaimo che che DE è un
singleton e che execute sia un metodo non-statico della classe,
supponiamo inoltre che il metodo req.getDEP() sia bloccante. Ciò
comporta che si bloccherebbe tutta l'esecuzione del metodo execute()
di DE giusto? cioè DE non sarebbe più in grado di accettare chiamate
al metodo execute() fino a che l'esecuzione non viene "sbloccata" dal
dal ritorno di req.getDEP() e, in questo modo, andrei a perdere il
parallelismo che cercavo...
Scusa l'eventuale stupidaggine che ho scritto ;)

Ciao
Sergio

sv

unread,
Dec 21, 2009, 4:21:22 AM12/21/09
to
sergio wrote:
> Grazie dei chiarimenti. Andr� subito a guardarmi i riferimenti che mi
> hai indicato.
> La questione dei thread e della concorrenza � una cosa che mi

> interessa molto e che vorrei approfondire per riuscire a muovermi
> agevolmente in questo ambito.


Concurrent Programming in Java: Design Principles and Patterns di Doug Lea

> Un'altra domanda, immagino banale ma che contribuisce a chiarirmi

> meglio i dubbi sulla sincronizzazione: supponaimo che che DE � un


> singleton e che execute sia un metodo non-statico della classe,

> supponiamo inoltre che il metodo req.getDEP() sia bloccante. Ci�


> comporta che si bloccherebbe tutta l'esecuzione del metodo execute()

> di DE giusto? cio� DE non sarebbe pi� in grado di accettare chiamate


> al metodo execute() fino a che l'esecuzione non viene "sbloccata" dal
> dal ritorno di req.getDEP() e, in questo modo, andrei a perdere il
> parallelismo che cercavo...
> Scusa l'eventuale stupidaggine che ho scritto ;)
>
> Ciao
> Sergio
>


si esatto, ci� deriva dal fatto che hai due metodi bloccanti innestati,
quindi req.getDEP(), quando metterebbe in wait il thread, ne potrebbe
accettare altri, ma execute() rimarrebbe comunque bloccata.

Il fatto � che per come hai strutturato l'applicazione, execute non
permette il parallelismo, visto che dovrebbe attendere la fine di un thread.

Mi permetto una piccola nota, credo che Semaphore sia da mettere a 1 e
non a 0, altrimenti il primo come fa ad entrare?


--
sv.

0 new messages