Lezione 2: I thread
      Corso di Programmazione in Rete
     Laurea Magistrale in Ing. Informatica
       Università degli Studi di Salerno



1
Outline
    ✦ Introduzione ai thread

    ✦ I thread in Java

    ✦ La sincronizzazione




2
Introduzione ai thread
    ✦ Sequenza statica = sequenza delle
      istruzioni nel testo del programma
    ✦ Sequenza dinamica = sequenza in cui le
      istruzioni sono eseguite durante una
      particolare esecuzione del programma
    ✦ Tradizionalmente, ad ogni esecuzione è
      associata un’unica sequenza statica detta
      anche flusso di esecuzione o thread of
      execution

3
Multi-threading
    ✦ Nei moderni sistemi operativi un
      programma può attivare più flussi di
      esecuzione (thread) che procedono
      simultaneamente
    ✦ I programmi che sfruttano questa
      possibilità sono detti multi-threaded
    ✦ Nota:
     •   Multitasking = più programmi attivi
         contemporaneamente
     •   Multithreading = più thread attivi nello stesso
         programma
4
Multi-threading
    ✦ In un programma a singolo thread:

                                            Operazione A {
                                                   istruzione 1
                                                   istruzione 2
              ...                                  ...
              OperazioneA();                }
              OperazioneB();
              ...
                                            Operazione B {
                                                   istruzione 1
        L'operazione A deve essere                 istruzione 2
        completata prima che il programma          ...
        possa cominciare l'operazione B     }




5
Multi-threading
    ✦ In un programma multi-threaded

                                               Operazione A {
          ...                                         istruzione 1
          nuovo thread {                              istruzione 2
            OperazioneA();                            ...
          }                                    }
          OperazioneB();
          ...
                                               Operazione B {
                                                      istruzione 1
       L’operazione A è eseguita in un                istruzione 2
       thread separato da quello                      ...
       principale; B comincia prima che A      }
       sia terminata
       (A e B sono eseguite “in parallelo”)‫‏‬




6
Multi-threading
    ✦ Se il computer ha più processori:
      esecuzione parallela dei thread
    ✦ Se il computer ha un solo processore (o
      un numero di processori inferiore al
      numero di thread): esecuzione
      concorrente (time sharing)
            esecuzione parallela   operazione A
                                     operazione B




            esecuzione                    operazione A
            concorrente
                                            operazione B


                                                         tempo
7
Vantaggi

    ✦ Sfruttare il parallelismo quando
      disponibile
    ✦ Operazioni lunghe in “background” senza
      bloccare il programma
    ✦ Alcuni programmi devono comunque
      gestire più richieste contemporaneamente
      (es. web server)



8
Svantaggi
    ✦ Ogni thread richiede memoria per lo stack
      e altre risorse
    ✦ Il passaggio del processore da un thread
      all’altro (context switch) non è
      un’operazione istantanea


      Quindi: non è conveniente avere un
      numero molto elevato di thread


9
Sincronizzazione
     ✦ I thread di un programma hanno tutti
       accesso alle risorse del programma e
       possono modificarne lo stato
     ✦ La modifica dello stato di una struttura
       dati simultaneamente da parte di più
       thread può portare la struttura dati in uno
       stato inconsistente
     ✦ È necessario un coordinamento tra i
       thread che devono accedere a una stessa
       struttura dati (sincronizzazione)

10
Sincronizzazione
     ✦ Esempio: supponiamo di avere una
       variabile condivisa SALDO che contenga il
       saldo di un conto corrente

           PRELIEVO:          VERSAMENTO:
                x ← SALDO          y ← SALDO
                x ← x-50           y ← y+75
                SALDO ← x          SALDO ← y


     ✦ Cosa succede se le due operazioni sono
       eseguite in due thread attivi
       simultaneamente?

11
I thread in Java
     ✦ In Java è possibile creare un nuovo
       thread usando la classe Thread
     ✦ Occorre associare il thread alle operazioni
       che deve svolgere
      •   Creazione di una sottoclasse di Thread
      •   Creazione di un oggetto che implementi
          l’interfaccia Runnable, da passare al costruttore di
          Thread
     ✦ Il thread deve essere avviato con il
       metodo start

12
Thread in Java
     ✦ Esempio
         public   class HelloThread extends Thread {
         	        public void run() {
         	        	      int i;
         		                for(i=0; i<100; i++)‫‏‬
         	        	      	      System.out.println("Hello, world");
                  }
         }
         public   class TestHello1 {
         	        public static void main(String[] args) {
         	        	      // Creazione e avvio di un nuovo thread
         	        	      Thread t=new HelloThread();
         	        	      t.start();
         	        	
         	        	      // Simultaneamente, nel thread del main...
         	        	      int i;
         		             for(i=0; i<100; i++)‫‏‬
         	        	      	      System.out.println("Salve, mondo");
         	        }
         }
13
Thread in Java
     ✦ Esempio
        public class HelloPrinter implements Runnable {
        	     public void run() {
        	     	     int i;
        		              for(i=0; i<100; i++)‫‏‬
        	     	     	     System.out.println("Hello, world");
        	     }
        }

        public   class TestHello2 {
        	        public static void main(String[] args) {
        	        	      // Creazione e avvio di un nuovo thread
        	        	      HelloPrinter hello=new HelloPrinter();
        	        	      Thread t=new Thread(hello);
        	        	      t.start();
        	        	
        	        	      // Simultaneamente, nel thread del main...
        	        	      int i;
        		              for(i=0; i<100; i++)‫‏‬
        	        	      	      System.out.println("Salve, mondo");
        	        }
        }
14
Daemon thread
     ✦ Un programma Java termina quando tutti
       i suoi thread sono terminati
     ✦ È possibile dichiarare un thread come “di
       servizio” (daemon thread) in modo che il
       programma termini quando sono rimasti
       attivi solo i thread di servizio
      •   A tale scopo si usa il metodo:
             void setDaemon(boolean isDaemon)
          della classe Thread prima di chiamare start()


15
Sincronizzazione in Java

     ✦ Ogni oggetto Java contiene una struttura
       dati detta mutex che consente di
       garantire che l’accesso all’oggetto venga
       effettuato da un solo thread per volta
       (“mutua esclusione”)
     ✦ Combinando l’uso del mutex con
       l’incapsulamento il programmatore può
       gestire il problema della sincronizzazione


16
Synchronized


     ✦ Il mutex di un oggetto si utilizza tramite il
       costrutto synchronized, la cui sintassi è:
             synchronized (obj) {
                              istruzione ...
               }




17
Synchronized
     ✦ Il thread che esegue synchronized
       “acquisisce” il mutex dell’oggetto indicato
       per tutta la durata del blocco di istruzioni
       specificato
     ✦ Un solo thread alla volta può acquisire un
       certo mutex
     ✦ Se un altro thread prova ad acquisire un
       mutex già impegnato da un altro thread,
       viene messo in attesa fino a quando
       l’altro thread non rilascia il mutex

18
Synchronized
     ✦ Esempio
           public class ContoCorrente {
           	 private double saldo;
           	
           	 public ContoCorrente(double saldoIniziale) {
           	 	 saldo=saldoIniziale;
           	 }
           	
           	 public double getSaldo() {
           	 	 synchronized (this) {
           	 	 	 return saldo;
           	 	 }
           	 }
           	
           	 public void versa(double x) {
           	 	 synchronized (this) {
           	 	 	 saldo+=x;
           	 	 }
           	 }
           }

19
Synchronized

     ✦ Spesso occorre rendere synchronized
       l’intero corpo di un metodo usando il
       mutex dell’oggetto corrente (this)
     ✦ Sintassi semplificata: premettere la
       parola chiave synchronized
       all’intestazione del metodo



20
Synchronized
     ✦ Esempio

           public class ContoCorrente {
           	 private double saldo;
           	
           	 public ContoCorrente(double saldoIniziale) {
           	 	 saldo=saldoIniziale;
           	 }
           	
           	 public synchronized double getSaldo() {
           	 	 	 	 return saldo;
           	 }
           	
           	 public synchronized void versa(double x) {
           	 	 	 saldo+=x;
           	 }
           }




21

Lezione 2: I thread

  • 1.
    Lezione 2: Ithread Corso di Programmazione in Rete Laurea Magistrale in Ing. Informatica Università degli Studi di Salerno 1
  • 2.
    Outline ✦ Introduzione ai thread ✦ I thread in Java ✦ La sincronizzazione 2
  • 3.
    Introduzione ai thread ✦ Sequenza statica = sequenza delle istruzioni nel testo del programma ✦ Sequenza dinamica = sequenza in cui le istruzioni sono eseguite durante una particolare esecuzione del programma ✦ Tradizionalmente, ad ogni esecuzione è associata un’unica sequenza statica detta anche flusso di esecuzione o thread of execution 3
  • 4.
    Multi-threading ✦ Nei moderni sistemi operativi un programma può attivare più flussi di esecuzione (thread) che procedono simultaneamente ✦ I programmi che sfruttano questa possibilità sono detti multi-threaded ✦ Nota: • Multitasking = più programmi attivi contemporaneamente • Multithreading = più thread attivi nello stesso programma 4
  • 5.
    Multi-threading ✦ In un programma a singolo thread: Operazione A { istruzione 1 istruzione 2 ... ... OperazioneA(); } OperazioneB(); ... Operazione B { istruzione 1 L'operazione A deve essere istruzione 2 completata prima che il programma ... possa cominciare l'operazione B } 5
  • 6.
    Multi-threading ✦ In un programma multi-threaded Operazione A { ... istruzione 1 nuovo thread { istruzione 2 OperazioneA(); ... } } OperazioneB(); ... Operazione B { istruzione 1 L’operazione A è eseguita in un istruzione 2 thread separato da quello ... principale; B comincia prima che A } sia terminata (A e B sono eseguite “in parallelo”)‫‏‬ 6
  • 7.
    Multi-threading ✦ Se il computer ha più processori: esecuzione parallela dei thread ✦ Se il computer ha un solo processore (o un numero di processori inferiore al numero di thread): esecuzione concorrente (time sharing) esecuzione parallela operazione A operazione B esecuzione operazione A concorrente operazione B tempo 7
  • 8.
    Vantaggi ✦ Sfruttare il parallelismo quando disponibile ✦ Operazioni lunghe in “background” senza bloccare il programma ✦ Alcuni programmi devono comunque gestire più richieste contemporaneamente (es. web server) 8
  • 9.
    Svantaggi ✦ Ogni thread richiede memoria per lo stack e altre risorse ✦ Il passaggio del processore da un thread all’altro (context switch) non è un’operazione istantanea Quindi: non è conveniente avere un numero molto elevato di thread 9
  • 10.
    Sincronizzazione ✦ I thread di un programma hanno tutti accesso alle risorse del programma e possono modificarne lo stato ✦ La modifica dello stato di una struttura dati simultaneamente da parte di più thread può portare la struttura dati in uno stato inconsistente ✦ È necessario un coordinamento tra i thread che devono accedere a una stessa struttura dati (sincronizzazione) 10
  • 11.
    Sincronizzazione ✦ Esempio: supponiamo di avere una variabile condivisa SALDO che contenga il saldo di un conto corrente PRELIEVO: VERSAMENTO: x ← SALDO y ← SALDO x ← x-50 y ← y+75 SALDO ← x SALDO ← y ✦ Cosa succede se le due operazioni sono eseguite in due thread attivi simultaneamente? 11
  • 12.
    I thread inJava ✦ In Java è possibile creare un nuovo thread usando la classe Thread ✦ Occorre associare il thread alle operazioni che deve svolgere • Creazione di una sottoclasse di Thread • Creazione di un oggetto che implementi l’interfaccia Runnable, da passare al costruttore di Thread ✦ Il thread deve essere avviato con il metodo start 12
  • 13.
    Thread in Java ✦ Esempio public class HelloThread extends Thread { public void run() { int i; for(i=0; i<100; i++)‫‏‬ System.out.println("Hello, world"); } } public class TestHello1 { public static void main(String[] args) { // Creazione e avvio di un nuovo thread Thread t=new HelloThread(); t.start(); // Simultaneamente, nel thread del main... int i; for(i=0; i<100; i++)‫‏‬ System.out.println("Salve, mondo"); } } 13
  • 14.
    Thread in Java ✦ Esempio public class HelloPrinter implements Runnable { public void run() { int i; for(i=0; i<100; i++)‫‏‬ System.out.println("Hello, world"); } } public class TestHello2 { public static void main(String[] args) { // Creazione e avvio di un nuovo thread HelloPrinter hello=new HelloPrinter(); Thread t=new Thread(hello); t.start(); // Simultaneamente, nel thread del main... int i; for(i=0; i<100; i++)‫‏‬ System.out.println("Salve, mondo"); } } 14
  • 15.
    Daemon thread ✦ Un programma Java termina quando tutti i suoi thread sono terminati ✦ È possibile dichiarare un thread come “di servizio” (daemon thread) in modo che il programma termini quando sono rimasti attivi solo i thread di servizio • A tale scopo si usa il metodo: void setDaemon(boolean isDaemon) della classe Thread prima di chiamare start() 15
  • 16.
    Sincronizzazione in Java ✦ Ogni oggetto Java contiene una struttura dati detta mutex che consente di garantire che l’accesso all’oggetto venga effettuato da un solo thread per volta (“mutua esclusione”) ✦ Combinando l’uso del mutex con l’incapsulamento il programmatore può gestire il problema della sincronizzazione 16
  • 17.
    Synchronized ✦ Il mutex di un oggetto si utilizza tramite il costrutto synchronized, la cui sintassi è: synchronized (obj) { istruzione ... } 17
  • 18.
    Synchronized ✦ Il thread che esegue synchronized “acquisisce” il mutex dell’oggetto indicato per tutta la durata del blocco di istruzioni specificato ✦ Un solo thread alla volta può acquisire un certo mutex ✦ Se un altro thread prova ad acquisire un mutex già impegnato da un altro thread, viene messo in attesa fino a quando l’altro thread non rilascia il mutex 18
  • 19.
    Synchronized ✦ Esempio public class ContoCorrente { private double saldo; public ContoCorrente(double saldoIniziale) { saldo=saldoIniziale; } public double getSaldo() { synchronized (this) { return saldo; } } public void versa(double x) { synchronized (this) { saldo+=x; } } } 19
  • 20.
    Synchronized ✦ Spesso occorre rendere synchronized l’intero corpo di un metodo usando il mutex dell’oggetto corrente (this) ✦ Sintassi semplificata: premettere la parola chiave synchronized all’intestazione del metodo 20
  • 21.
    Synchronized ✦ Esempio public class ContoCorrente { private double saldo; public ContoCorrente(double saldoIniziale) { saldo=saldoIniziale; } public synchronized double getSaldo() { return saldo; } public synchronized void versa(double x) { saldo+=x; } } 21