Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    [JAVA] Problema con Sleep()

    Dalla definizione della sun:

    The thread does not lose ownership of any monitors.

    Sono sicuro di sbagliare qualcosa nel codice, ma l'output andrebbe contro ciò che è scritto dalla sun...

    public class Thread2 implements Runnable{

    @Override
    public void run() {

    this.m.divisione();
    try {
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    System.out.println("FINITO THREAD");
    }

    public Thread2 (MetodoSincronizzato c) {

    this.m = c;

    }

    public MetodoSincronizzato m;



    }
    ------------------------------------
    public class MetodoSincronizzato {

    public synchronized void divisione() {

    System.out.println (this.a + " diviso " + this.b + " è uguale a " + this.a/this.b + " con resto " + this.a%this.b + ".");

    }

    public MetodoSincronizzato(int a, int b){

    this.a = a;
    this.b = b;

    }
    private int a, b;
    }
    ------------------------------------
    public class MaineRoad {


    public static void main (String[] args){
    MetodoSincronizzato c = new MetodoSincronizzato(11, 4);
    Runnable a = new Thread2 (c);
    Runnable b = new Thread2 (c);
    Thread t1 = new Thread (a, "CICCIO");
    Thread t2 = new Thread (b, "PASTICCIO");


    t1.start();
    t2.start();
    try {
    Thread.sleep(4000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }



    }

    }
    In pratica i due oggetti Thread2 prendono come parametro lo stesso oggetto MetodoSerializzato, e nel loro accedere ad un metodo di quell'oggetto dovrebbero averne l'accesso esclusivo fino a terminazione.
    Eppure l'output è questo:

    11 diviso 4 è uguale a 2 con resto 3.
    11 diviso 4 è uguale a 2 con resto 3.
    FINITO THREAD
    FINITO THREAD

    invece dell'atteso

    11 diviso 4 è uguale a 2 con resto 3.
    FINITO THREAD
    11 diviso 4 è uguale a 2 con resto 3.
    FINITO THREAD

    Perchè?

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

    Re: [JAVA] Problema con Sleep()

    Originariamente inviato da ragnonerodocet
    Dalla definizione della sun:

    The thread does not lose ownership of any monitors.
    Vuol semplicemente dire che un thread che è in stato di sleep non rilascia alcun lock (come invece fa wait())

    Originariamente inviato da ragnonerodocet
    In pratica i due oggetti Thread2 prendono come parametro lo stesso oggetto MetodoSerializzato, e nel loro accedere ad un metodo di quell'oggetto dovrebbero averne l'accesso esclusivo fino a terminazione.
    Eppure l'output è questo:

    11 diviso 4 è uguale a 2 con resto 3.
    11 diviso 4 è uguale a 2 con resto 3.
    FINITO THREAD
    FINITO THREAD

    invece dell'atteso

    11 diviso 4 è uguale a 2 con resto 3.
    FINITO THREAD
    11 diviso 4 è uguale a 2 con resto 3.
    FINITO THREAD

    Perchè?
    Perché l'unico punto dove c'è una "serializzazione" è la invocazione del metodo synchronized divisione() da parte dei 2 thread sullo stesso oggetto che è condiviso (quindi il lock è lo stesso).
    Per il resto i thread viaggiano per conto proprio.
    Quando il thread è nella sleep, non ha aquisito alcun lock!!

    Per dirlo in altro modo: l'unica cosa sicura è che solamente 1 thread per volta può eseguire il metodo divisione().
    Non c'è niente, nel codice, che impone che la sequenza divisione()+sleep()+stampa "FINITO...." venga eseguita in modo "atomico".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Quando il Thread main va in sleep, sui thread t1 e t2 è stato già invocato il metodo start().

    Ora t1 sarà il primo ad essere scelto dallo scheduler perchè da più tempo in attesa:

    se ho capito bene, il primo thread, diciamo t1, una volta scelto dallo scheduler, fa questo:

    1-chiama sull'oggetto MetodoSincronizzato m il metodo divisione: a questo punto è tale metodo SOLTANTO ad essere sincronizzato!!! Dunque esegue SOLO il metodo in maniera atomica!!! Quindi prende il lock e poi subito finito il metodo lo rilascia...

    2-va in sleep e il secondo thread, t2, fa lo stesso, cioè esegue il metodo e va in sleep.

    3- nel frattempo, si è svegliato il thread main. Subito dopo muore.

    4- si sveglia t1, stampa FINITO THREAD e muore.

    5- stessa sorte per t2.

    Giusto?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da ragnonerodocet
    Quando il Thread main va in sleep, sui thread t1 e t2 è stato già invocato il metodo start().
    Questo è certo.

    Originariamente inviato da ragnonerodocet
    Ora t1 sarà il primo ad essere scelto dallo scheduler perchè da più tempo in attesa:
    No, non è affatto detto. Non c'è alcuna garanzia che i thread inizieranno il loro lavoro nello stesso ordine con cui sono state fatte le start().
    start() fa solo entrare il thread nello stato di "runnable". Cosa poi scelga lo scheduler sono fatti suoi.

    Originariamente inviato da ragnonerodocet
    1-chiama sull'oggetto MetodoSincronizzato m il metodo divisione: a questo punto è tale metodo SOLTANTO ad essere sincronizzato!!! Dunque esegue SOLO il metodo in maniera atomica!!! Quindi prende il lock e poi subito finito il metodo lo rilascia...
    Sì, esatto. Questo è ciò che è sicuro.
    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.