Salve,
è possibile impostare un timeout sul Thread, così da far cessare il processo dopo un tot minuti??
Salve,
è possibile impostare un timeout sul Thread, così da far cessare il processo dopo un tot minuti??
No e non ha molto senso...
O progetti il thread in modo da terminare il metodo run() se sono trascorsi tot minuti o crei un secondo thread che tiene il tempo e, eventualmente, ferma il primo.
La seconda è più semplice.
Ciao.![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
si effettivamente avevo pensato alla seconda soluzione.Originariamente inviato da LeleFT
No e non ha molto senso...
O progetti il thread in modo da terminare il metodo run() se sono trascorsi tot minuti o crei un secondo thread che tiene il tempo e, eventualmente, ferma il primo.
La seconda è più semplice.
Ciao.![]()
Allora partiamo dall'inizio, io all'interno del thread passo una socket aperta con un client e resto in attesa che lui mi mandi qualcosa nel buffer. Dopo un paio di secondi (con il setSoTimeout) interrompo la read eseguo dei controlli miei e ritorno nella read... e cosi ciclicamente finchè la comunicazione e il Thread non termini dopo aver eseguito tutte le procedure con il client.
Adesso io vorrei anche poter interrompere il Thread con un timer, perchè se ad esempio la comunicazione con il client venisse a mancare io resto appeso a quel ciclo perennemente(ho già provato), a meno che ad ogni ciclo non invio qualcosa al client e vedendo che non risponde, ottengo un eccezione e chiudo il Thread ma purtroppo non posso farlo. E cmq se per qualsiasi motivo il Thread restasse appeso vorrei che passato un tempo massimo, venisse chiuso definitivamente.
Cosi ho creato un secondo thread che esegue lo stop() del primo, ma è come se il thread o non venisse terminato oppure viene terminato ma continuo a restare all'interno del ciclo del read.
Terminando il Thread mi dovrebbe eliminare tutte le operazioni che lui stava eseguendo al suo interno.
Andiamo con ordine.
1) Se il client si disconnette, la read() va in eccezione. Ma non solleva una SocketTimeoutException, bensì verrà sollevata una generica IOException. Mi sembra chiaro che le due vadano gestite separatamente e questo dovrebbe permetterti di non rimanere appeso sulla read. Esempio:
2) Non va mai usato il metodo stop() di Thread: è deprecato ed è spiegato anche il perchè. Se vuoi interrompere un thread in modo brutale devi usare interrupt().codice:try { ... // Sto effettuando la read() dalla Socket } catch (SocketTimeoutException ste) { // La read è andata in timeout... posso provare a farne un'altra } catch (IOException ioe) { // E' successo qualcos'altro: è inutile entrare di nuovo nella read() }
3) Consiglio, dove possibile, di non optare per interrupt(): il thread che effettua la read() sulla Socket dovrebbe essere collaborativo. Questo significa che, prima di effettuare la read() dovrebbe porsi il problema di essere stato bloccato da qualcun altro. Basta una semplice variabile booleana: se essa è a true, allora il thread effettua le read(), altrimenti non fa nulla e lascia che il metodo run() termini. In questo modo, puoi controllare dall'esterno il thread: ti basterà richiamare un metodo che imposta a false tale variabile e, al più TOT minuti dopo, il thread si fermerà:
Ciao.codice:// Nel metodo run() try { if ( sonoAttivo ) { ... // Effettuo la read() } } catch (SocketTimeoutException ste) { ... } ... // Un metodo pubblico per fermare il thread public void ferma() { sonoAttivo = false; }![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
1. Allora per quanto riguarda l'eccezione, se è il client a chiudere volontariamente la connessione l'eccezione viene generata ma se invece al client viene a mancare la connessione (ho fatto una prova a staccare il cavo di rete), il server resta appeso al ciclo.
2. Per quanto riguarda interrupt(), ho usato anche quello ma non chiude brutalmente il Thread, ho notato che serve per impostare una flag, infatti, come dicevi tu, usavo quello per controllare se il Threah fossi interrotto con Thread.currentThread().isInterrupted() ed eventualmente gli facevo terminare il ciclo ed usciva dal Thread normalmente.
3. Quella della flag può essere una soluzione ma mettiamo che all'interno del Thread ci sia qualche altro processo che resta fermo, per qualsiasi motivo... io non posso vorrei poterlo chiudere brutalmente dopo un tempo limite.
In questo caso puoi fare ben poco. Se non implementando un sistema di ACK per i momenti "di inattività".Originariamente inviato da hackerdm
1. Allora per quanto riguarda l'eccezione, se è il client a chiudere volontariamente la connessione l'eccezione viene generata ma se invece al client viene a mancare la connessione (ho fatto una prova a staccare il cavo di rete), il server resta appeso al ciclo.
Sì, viene impostato il flag e questo, nella maggior parte dei casi, dovrebbe causare l'interruzione del thread. Esistono diverse casistiche ben documentate del metodo interrupt() di Thread. Se nessuna di quelle casistiche viene soddisfatta, tutto ciò che può essere fatto è l'impostazione del flag e basta.2. Per quanto riguarda interrupt(), ho usato anche quello ma non chiude brutalmente il Thread, ho notato che serve per impostare una flag, infatti, come dicevi tu, usavo quello per controllare se il Threah fossi interrotto con Thread.currentThread().isInterrupted() ed eventualmente gli facevo terminare il ciclo ed usciva dal Thread normalmente.
Se i processi interni al thread non sono collaborativi, anche in questo caso, non è che si possa fare gran ché.3. Quella della flag può essere una soluzione ma mettiamo che all'interno del Thread ci sia qualche altro processo che resta fermo, per qualsiasi motivo... io non posso vorrei poterlo chiudere brutalmente dopo un tempo limite.
Devo dire che di applicazioni client/server ne ho create parecchie e non mi sono mai scontrato con tutti questi problemi contemporaneamente. In particolare, non sono mai dovuto ricorrere all'uso di interrupt(): ho sempre progettato i thread in modo collaborativo e non ho mai avuto problemi.
Ciao.![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
che intendi per
Se non implementando un sistema di ACK per i momenti "di inattività".
Aprendo un'altra piccola parentesi:
come già ben sai ho aperto un secondo Thread che fa da timer per il primo Thread, se il primo Thread finisce prima dello scadere del timer devo in qualche modo gestirmi la chiusura del secondo thread. Tu come ti comporteresti?
Idem, mai usato interruptOriginariamente inviato da LeleFT
In particolare, non sono mai dovuto ricorrere all'uso di interrupt(): ho sempre progettato i thread in modo collaborativo e non ho mai avuto problemi.
Il centro dell'attenzione non è sempre un buon posto in cui trovarsi
Mai discutere con uno stupido, la gente potrebbe non capire la differenza. (O. W.)
Mi pare che l'avessi già proposta anche tu nel secondo post: ad ogni ciclo, se la read() va in timeout, invii qualcosa al client e verifichi che questo risponda (un ACK). Se non risponde è probabile che qualcosa sia andato storto.Originariamente inviato da hackerdm
che intendi per
Se non implementando un sistema di ACK per i momenti "di inattività".
Beh, ci possono essere diverse soluzioni. Al momento mi vengono in mente queste due:Aprendo un'altra piccola parentesi:
come già ben sai ho aperto un secondo Thread che fa da timer per il primo Thread, se il primo Thread finisce prima dello scadere del timer devo in qualche modo gestirmi la chiusura del secondo thread. Tu come ti comporteresti?
1) Il thread che fa da timer, non si limita ad aspettare che passino TOT minuti prima di intervenire sul thread principale. Molto più semplicemente, dovrebbe continuare a verificare che il thread principale sia in vita MENTRE aspetta. Per dirla breve: il timer non dovrebbe mettersi in sleep per X minuti, ma dovrebbe ciclare (X * 60) volte e, ad ogni ciclo (quindi, ogni secondo), testare l'attività del thread principale. Se il thread è già morto, è inutile che lui continui...
2) I due thread sono avviati separatamente dall'applicazione che si preoccupa di controllare la terminazione di quello principale. Quando questo termina, essa uccide il thread timer.
Ciao.![]()
"Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza
grazie mille per i tuoi aiuti, te ne sono grato