Visualizzazione dei risultati da 1 a 8 su 8

Discussione: [JAVA] Thread

  1. #1

    [JAVA] Thread

    La parte più difficile per superare il mio esame è questa. Inizio con le domande sperando nella magnanimità di qualcuno... Andvin, per citare una persona a caso

    Esistono svariati metodi applicabili sui Threads.

    In questo caso mi riferisco a join() e yield().

    Il primo metodo ha questa spiegazione

    one thread can wait for another to complete using the join() method

    Non ho capito bene cosa faccia join, e soprattutto non ho trovato neanche un esempio che mi spieghi cosa faccia...
    In pratica, chiamando join() sul thread corrente, il thread aspetta (liberando le risorse???) che un altro Thread, passato dallo stato runnable a running, termini il suo metodo run() per poi lasciare la CPU al primo thread?

    Passiamo a yield().

    Che differenza c'è con join()??? La spiegazione è questa

    sospende l'esecuzione del thread invocante, lasciando il controllo della CPU agli altri thread in coda d'attesa...

    Soprattutto, qualcuno sarebbe così gentile da farmi qualche esempio illuminante per farmi capire quale sia la differenza tra i due metodi?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,280

    Re: [JAVA] Thread

    Originariamente inviato da ragnonerodocet
    Il primo metodo ha questa spiegazione

    one thread can wait for another to complete using the join() method

    Non ho capito bene cosa faccia join, e soprattutto non ho trovato neanche un esempio che mi spieghi cosa faccia...
    join() serve per bloccare il thread corrente nell'attesa che un "altro" thread termini. Questo "altro" thread è il Thread su cui si è invocato il join().

    codice:
    Thread t = ......
    
    t.start();   // avvio il nuovo thread
    
    t.join();    // resto bloccato qui, dentro il join(), in attesa che il thread referenziato da 't' termini
    Originariamente inviato da ragnonerodocet
    Passiamo a yield().

    Che differenza c'è con join()??? La spiegazione è questa

    sospende l'esecuzione del thread invocante, lasciando il controllo della CPU agli altri thread in coda d'attesa...
    yield() non centra nulla con join(), è tutta un'altra cosa.

    Partiamo da una premessa, in generale (quindi non centra solo Java), per farti capire: i moderni sistemi operativi usano un multi-tasking di tipo "preemptive", ovvero ad ogni thread viene dato di volta in volta, in modo ciclico, un "time slice" cioè una porzione del tempo della CPU e finito il time-slice, è il sistema operativo che "toglie" la CPU al thread per poter dare ad un altro thread la possibilità di proseguire il suo lavoro per un'altra porzione di tempo. E la cosa va avanti così.
    Lo "yield", inteso in generale, è il rilascio del tempo della CPU da parte di un thread in anticipo rispetto al momento in cui sarà il S.O. a togliere forzatamente la CPU al thread. È in pratica un rilascio "volontario" del tempo di CPU a favore di un altro thread.

    A questo punto ti chiederai: a cosa serve? Beh in Java yield() non serve generalmente a molto (ed è quindi raro doverlo usare!).

    La invocazione di yield() non dà alcuna garanzia, nel senso che la JVM potrebbe ignorare tale richiesta. E anche ammesso che yield() sia gestito dalla JVM, è possibile che il thread che ha rilasciato volontariamente la CPU venga subito riscelto tra tutti gli altri thread.

    Ci sarebbe da parlare di piu su questo argomento, comunque spero ti basti.

    Nota che join() è un metodo di istanza, lo si invoca su una istanza di Thread per attenderne la terminazione. yield() è static ... non lo si invoca su una istanza di Thread (non avrebbe senso) ma serve per sospendere il thread corrente.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Ho capito benissimo lo yield, ma sinceramente join mi è ancora oscuro...

    Ho un thread currentThread in esecuzione.
    Poi, ho un altro Thread, chiamato secondThread, su cui invoco start.
    Normalmente, il currentThread finisce il suo flusso dopo aver svolto il suo metodo run(). Dopodiche, terminato il currentThread, la JVM si accorge che c'è un altro Thread in attesa in stato runnable. Essendo l'unico Thread (mettiamola così...) passa alla CPU dove anch'esso svolge il suo metodo run().

    Se invece ci fosse, ad un certo punto del codice in cui currentThread è ancora in esecuzione, una chiamata del tipo

    secondThread.join()

    il secondThread avrebbe immediato(???) accesso alla CPU, dove svolgerebbe comodamente i suoi affari, fino alla terminazione.
    Domanda:

    quando il secondThread ha finito i suoi comodi, chi è che ha accesso alla CPU???
    Sempre e comunque il currentThread oppure un Thread scelto dallo scheduler con priorità massima o, a parità di priorità, che aspetta da più tempo?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,280
    Originariamente inviato da ragnonerodocet
    ma sinceramente join mi è ancora oscuro...
    Se io faccio:

    codice:
    Thread t = ......
    
    t.start();   // avvio il nuovo thread
    
    ..... altre istruzioni ...
    Il nuovo thread (quello avviato con start() "gira" in "parallelo" al thread corrente cioè mentre le "altre istruzioni" vengono eseguite nel thread corrente, il run() del nuovo thread ha modo di proseguire la sua esecuzione.

    Se però nel thread corrente faccio:

    t.join()

    Il thread corrente si blocca, proprio lì dentro nella join() in attesa che quell'altro thread avviato arrivi a terminazione.

    codice:
                             t.start()        t.join()
                                 |                |
    thread corrente    ============================ ....wait.... ======= = =
    
    thread 't'                   I===============================F
                       -------------------------------------------------------> tempo
    
    I = inizio del run()
    F = fine del run()
    Quando il thread corrente fa lo start dell'altro thread, quest'ultimo parte e va per conto suo e il thread corrente pure continua per conto suo con le istruzioni che seguono dopo lo start().

    Quando il thread corrente fa il join sull'altro thread, si blocca (viene proprio sospeso) e attende la terminazione dell'altro thread e poi riprende la sua esecuzione appena l'altro thread è terminato.

    Più chiaro ora?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Tutto chiarissimo mediante disegno illuminante...

    E alla fine del join va nella CPU il Thread nello stato runnable con priorità massima (fatto dallo scheduler).

    Giusto?

    O in qualche modo il thread che contiene la join è privilegiato nel concorrere alla CPU?

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,280
    Originariamente inviato da ragnonerodocet
    E alla fine del join va nella CPU il Thread nello stato runnable con priorità massima (fatto dallo scheduler).

    Giusto?

    O in qualche modo il thread che contiene la join è privilegiato nel concorrere alla CPU?
    No, non c'è alcun "privilegio", solo per il fatto di aver invocato join().

    Invocando join(), il thread corrente va nello stato di "runnable". Quello che è certo è che tornerà in "running" solamente dopo che il thread su cui si è fatto il join() è terminato.
    Ma quale thread di volta in volta lo scheduler sceglie da far andare in running, sono questioni sue. E centra comunque pure la priorità dei Thread.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Mamma mia ho capito la join.

    Però adesso adesso stavo facendo un semplicissimo programma di prova per testare le differenze tra join() e yield().

    Ho capito che, mentre join serve affinchè un thread possa "improvvisamente" svolgere un compito prendendosi tutta la sua beata CPU, la yield blocca il thread corrente per vedere se, nella coda alla CPU, c'è un thread con priorità maggiore di quella del currentThread.

    In pratica, join ha SEMPRE effetto, perchè è invocata su uno specifico Thread, che prende SUBITO la CPU, svolge il suo compito, e poi rilascia il processore affinchè altri Thread possano usufruirne.

    Il metodo Yield invece controlla che nella coda per l'accesso alla CPU non ci siano altri Thread con priorità >= al Thread corrente. In caso ci siano, dà a loro la risorsa.
    In caso non ci siano, NON HA EFFETTO...

    Tutto vero?

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,280
    Originariamente inviato da ragnonerodocet
    join serve affinchè un thread possa "improvvisamente" svolgere un compito prendendosi tutta la sua beata CPU
    No, serve per attendere la fine di un altro thread. Punto.

    Originariamente inviato da ragnonerodocet
    la yield blocca il thread corrente per vedere se, nella coda alla CPU, c'è un thread con priorità maggiore di quella del currentThread.
    yield(), ammesso che la JVM non lo ignori, serve solamente per rilasciare "volontariamente" l'uso della CPU. Quale thread verrà fatto passare successivamente allo stato running, dipende dallo scheduler, non centra nulla direttamente con yield().
    Centra semmai con la priorità dei Thread, ma questo vale in generale.

    Originariamente inviato da ragnonerodocet
    In pratica, join ha SEMPRE effetto, perchè è invocata su uno specifico Thread, che prende SUBITO la CPU
    Non c'è nulla che "prende" la CPU. Ripeto, join() fa in modo che il thread corrente sia sospeso fino a quando l'altro thread è finito. Quando l'altro thread è finito, il thread sospeso ritorna in runnable e passerà a running appena possibile.

    (nota: nel precedente messaggio ho sbagliato a dire che va subito in runnable No viene sospeso)

    Originariamente inviato da ragnonerodocet
    Il metodo Yield invece controlla che nella coda per l'accesso alla CPU non ci siano altri Thread con priorità >= al Thread corrente.
    yield() non controlla un bel nulla. Rilascia la CPU e basta. Cosa succederà dopo dipende dallo scheduler.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.