Esercizio Thread - metodo static

di il
20 risposte

20 Risposte - Pagina 2

  • Re: Esercizio Thread - metodo static

    violet_prog ha scritto:


    Questo controllo l'ho aggiunto per trattare il caso suddetto in cui l'array contiene stringhe della lunghezza di s, ma non contiene s stessa. In questo caso ho immaginato che nè il primo thread (che non trova la stringa uguale) e nè il secondo thread (che trova almeno una stringa di uguale lunghezza) aggiungono rispettivamente true o false alla coda, e quindi se alla fine del ciclo del primo thread la coda risulta ancora vuota vuol dire che la stringa non c'è.
    Ma ti ripeto che non serve vedere se la coda è vuota. Ciascun thread, qualunque sia il suo flusso di esecuzione, deve fare al massimo 1 put. Tra i due thread deve essere certo che take() possa prendere 1 valore. Il T1 può dire sia true sia false. Il T2 che si basa solo sulle lunghezze, può solamente dire false al massimo. Non può dire true perché se trova la lunghezza uguale, il contenuto può essere diverso.
    Ma questo è sufficiente per garantire almeno 1 risultato!

    Se la capacity è 2, nessun put quindi si "bloccherà" in attesa che la coda venga svuotata (dal thread che esegue findString).
    Il primo che arriva a fare un put ... è il risultato che take() fornirà. Tutto qui.

    Esattamente... Quello che mi chiedevo era appunto se, nonostante in questo caso non richiamo nè sleep, nè wait, fosse comunque necessario chiamare interrupt() che come appunto so non interrompe il thread ma setta la flag di interruzione a true. Quindi la risposta è si. E' comunque sempre necessario, quindi devo sempre considerare questa cosa, giusto?!
    Penso di usare isInterrupted() in quanto, interrupted() oltre al controllo resetta la flag, è corretto?
    Se vuoi terminare i thread prima della loro fine "naturale" è ovvio che DEVI fare tu "qualcosa". Quindi il interrupt() sui due thread è necessario se vuoi la terminazione anticipata. Il fatto che tu nei thread devi verificare "sono stato interrotto?" è semplicemente perché nel tuo caso non c'è nulla nei thread che è veramente "bloccante" (I/O, sleep, wait(), ecc..) perché fanno principalmente computazioni (cicli, equals ecc..) e questo il interrupt() NON le interrompe.

    Riguardo la differenza tra interrupted() e isInterrupted() il discorso cambia in base al contesto. Ad esempio: sto sviluppando una libreria (che non so da chi sarà usata). Un metodo della libreria è bloccante o computazionalmente "pesante". Quindi è bene rendere il metodo "cooperativo" alla terminazione. Supponiamo che faccia solo computazioni (per semplicità, ora). Posso decidere di usare nel metodo isInterrupted() (che NON resetta il flag di interruzione), così il metodo può verificarlo, fare eventuali cleanup/rilasci di risorse e poi uscire subito. Ma il flag resta settato, così un qualunque "chiamante" può accorgersi che c'è stata terminazione e quindi magari fare altro.
    Questa ampiezza nel design nel tuo caso non è molto rilevante, Perché è tutto sotto il tuo controllo, nessun altro "sa" di quei thread ecc...
    Quindi che resetti il flag o no ... è poco importante nel tuo caso.
  • Re: Esercizio Thread - metodo static

    andbin ha scritto:


    Ma ti ripeto che non serve vedere se la coda è vuota. Ciascun thread, qualunque sia il suo flusso di esecuzione, deve fare al massimo 1 put. Tra i due thread deve essere certo che take() possa prendere 1 valore. Il T1 può dire sia true sia false. Il T2 che si basa solo sulle lunghezze, può solamente dire false al massimo. Non può dire true perché se trova la lunghezza uguale, il contenuto può essere diverso.
    Ma questo è sufficiente per garantire almeno 1 risultato
    Se la capacity è 2, nessun put quindi si "bloccherà" in attesa che la coda venga svuotata (dal thread che esegue findString).
    Il primo che arriva a fare un put ... è il risultato che take() fornirà. Tutto qui.
    Si ho capito ora quello che intendi, però eliminando quel controllo sulla coda, resta comunque il try catch con put(false)? Altrimenti non so in quale altro modo il t1 possa dire false.
    Se vuoi terminare i thread prima della loro fine "naturale" è ovvio che DEVI fare tu "qualcosa". Quindi il interrupt() sui due thread è necessario se vuoi la terminazione anticipata. Il fatto che tu nei thread devi verificare "sono stato interrotto?" è semplicemente perché nel tuo caso non c'è nulla nei thread che è veramente "bloccante" (I/O, sleep, wait(), ecc..) perché fanno principalmente computazioni (cicli, equals ecc..) e questo il interrupt() NON le interrompe.
    Purtroppo c'è qualcosa che non mi è chiaro.
    Ho capito che se voglio terminare i thread prima della loro terminazione naturale devo fare qualcosa.. Uno dei modi in cui termina un thread è con il return del metodo run(), quindi, ad esempio nel caso di t1 : "t1.interrupt()" dopo il take(), assieme al controllo "if(isInterrupted()) return;" mi assicura la terminazione del thread. E' così? - Diverso sarebbe stato il caso in cui il run() conteneva un metodo bloccante.
  • Re: Esercizio Thread - metodo static

    violet_prog ha scritto:


    Si ho capito ora quello che intendi, però eliminando quel controllo sulla coda, resta comunque il try catch con put(false)? Altrimenti non so in quale altro modo il t1 possa dire false.
    Ma infatti quel put(false) SERVE, è quel caso che AnMa giustamente ha fatto notate (e che a me era sfuggito prima). E serve anche il try-catch. put() tecnicamente è "bloccante" e infatti dichiara InterruptedException che è una eccezione "checked" e quindi VA considerata.

    Come ho detto prima, se ciascun thread fa al massimo 1 put e la coda ha capacity 2, nessun put di fatto si "blocca" (in attesa di spazio libero).
    Purtroppo c'è qualcosa che non mi è chiaro.
    Ho capito che se voglio terminare i thread prima della loro terminazione naturale devo fare qualcosa.. Uno dei modi in cui termina un thread è con il return del metodo run(), quindi, ad esempio nel caso di t1 : "t1.interrupt()" dopo il take(), assieme al controllo "if(isInterrupted()) return;" mi assicura la terminazione del thread. E' così?
    Sì, esatto.
  • Re: Esercizio Thread - metodo static

    andbin ha scritto:


    violet_prog ha scritto:


    Si ho capito ora quello che intendi, però eliminando quel controllo sulla coda, resta comunque il try catch con put(false)? Altrimenti non so in quale altro modo il t1 possa dire false.
    Ma infatti quel put(false) SERVE, è quel caso che AnMa giustamente ha fatto notate (e che a me era sfuggito prima). E serve anche il try-catch. put() tecnicamente è "bloccante" e infatti dichiara InterruptedException che è una eccezione "checked" e quindi VA considerata.

    Come ho detto prima, se ciascun thread fa al massimo 1 put e la coda ha capacity 2, nessun put di fatto si "blocca" (in attesa di spazio libero).
    Purtroppo c'è qualcosa che non mi è chiaro.
    Ho capito che se voglio terminare i thread prima della loro terminazione naturale devo fare qualcosa.. Uno dei modi in cui termina un thread è con il return del metodo run(), quindi, ad esempio nel caso di t1 : "t1.interrupt()" dopo il take(), assieme al controllo "if(isInterrupted()) return;" mi assicura la terminazione del thread. E' così?
    Sì, esatto.
    La cosa che mi resta poco chiara è la seguente.. Il mio codice senza t1.interrupt(), t2.interrupt() ed i rispettivi controlli, è sbagliato? I thread in questo caso non terminano naturalmente al termine del metodo findString?
  • Re: Esercizio Thread - metodo static

    violet_prog ha scritto:


    La cosa che mi resta poco chiara è la seguente.. Il mio codice senza t1.interrupt(), t2.interrupt() ed i rispettivi controlli, è sbagliato?
    Sbagliato nel senso di bacato o palesemente errato NO. Semplicemente ha una feature in meno, non interrompe i thread per evitare che vadano avanti inutilmente.
    Se vogliamo fare i fini/pignoli sarebbe anche buono oltre agli interrupt fare il join() sui thread per far sì che alla terminazione del findString siamo sicuri che i thread siano davvero terminati.
    Gli interrupt() sono di fatto immediati (non attendono nulla), quindi findString() termina subito dopo mentre i due thread potrebbero andare ancora un pelino avanti fino al punto successivo in cui c'è il controllo "sono stato interrotto?". Vedi risposta sotto.

    violet_prog ha scritto:


    I thread in questo caso non terminano naturalmente al termine del metodo findString?
    No, senza gli interrupt() i thread tecnicamente potrebbero andare avanti (immagina se l'array avesse migliaia di elementi) anche DOPO che findString è terminato.
  • Re: Esercizio Thread - metodo static

    andbin ha scritto:


    violet_prog ha scritto:


    La cosa che mi resta poco chiara è la seguente.. Il mio codice senza t1.interrupt(), t2.interrupt() ed i rispettivi controlli, è sbagliato?
    Sbagliato nel senso di bacato o palesemente errato NO. Semplicemente ha una feature in meno, non interrompe i thread per evitare che vadano avanti inutilmente.
    Se vogliamo fare i fini/pignoli sarebbe anche buono oltre agli interrupt fare il join() sui thread per far sì che alla terminazione del findString siamo sicuri che i thread siano davvero terminati.
    Gli interrupt() sono di fatto immediati (non attendono nulla), quindi findString() termina subito dopo mentre i due thread potrebbero andare ancora un pelino avanti fino al punto successivo in cui c'è il controllo "sono stato interrotto?". Vedi risposta sotto.

    violet_prog ha scritto:


    I thread in questo caso non terminano naturalmente al termine del metodo findString?
    No, senza gli interrupt() i thread tecnicamente potrebbero andare avanti (immagina se l'array avesse migliaia di elementi) anche DOPO che findString è terminato.
    Perfetto! Grazie mille!!!
Devi accedere o registrarti per scrivere nel forum
20 risposte