> For the complete documentation index, see [llms.txt](https://checksound.gitbook.io/corsojava/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://checksound.gitbook.io/corsojava/i-thread-e-concorrenza/esercizi-multithreading.md).

# Esercizi multithreading

### 1 - Possibili flussi&#x20;

Dato il seguente codice:

```java
class EsempioThread extends Thread {

    public void run() {
	System.out.println("THREAD_A");
    	System.out.println("THREAD_B");
    	System.out.println("THREAD_C");
    	System.out.println("THREAD_D");
    	System.out.println("THREAD_E");
    }
	
    public static void main(String[] args) 
        throws InterruptedException {

        EsempioThread t1 = new EsempioThread();
        t1.start();

        // t1.join();

        System.out.println("MAIN_A");
        System.out.println("MAIN_B");
        System.out.println("MAIN_C");
        System.out.println("MAIN_D");
        System.out.println("MAIN_E");

  }
	
}
```

Quali sono i possibili flussi di esecuzione delle istruzioni?

Esempi di flussi possibili (il simbolo A < B vuol dire che l'istruzione A è eseguita prima di B):&#x20;

* `MAIN_A < MAIN_B < MAIN_C < MAIN_D < THREAD_A < THREAD_B < THREAD_C < THREAD_D < THREAD_E < MAIN_E`&#x20;
* `MAIN_A < MAIN_B < THREAD_A < MAIN_C < THREAD_B < THREAD_C < MAIN_D < MAIN_E < THREAD_D < THREAD_E`&#x20;
* `THREAD_A < MAIN_A < THREAD_B < MAIN_B <THREAD_C < MAIN_C < THREAD_D < MAIN_D < THREAD_E < MAIN_E`

Mentre ad esempio il seguente flusso non è possibile:

* `MAIN_A < THREAD_B < THREAD_A < MAIN_B < MAIN_D < MAIN_C < THREAD_C < THREAD_D < MAIN_E < THREAD_E`

Vedi esempio:

{% code lineNumbers="true" %}

```java

class EsempioThreadMain {

	static class EsempioThread extends Thread {

		public void run() {
		
			try {
			  System.out.println("THREAD_A");
			  sleep(10);
			  System.out.println("THREAD_B");
			  sleep(10);
			  System.out.println("THREAD_C");
			  sleep(10);
			  System.out.println("THREAD_D");
			  sleep(10);
			  System.out.println("THREAD_E");
			  sleep(10);
			  
			} catch (InterruptedException e) {}		
	
		}
	}


  public static void main(String[] args) throws InterruptedException {

    EsempioThread t1 = new EsempioThread();
    t1.start();

    //t1.join();

    System.out.println("MAIN_A");
    Thread.sleep(10);
    System.out.println("MAIN_B");
    Thread.sleep(10);
    System.out.println("MAIN_C");
    Thread.sleep(10);
    System.out.println("MAIN_D");
    Thread.sleep(10);
    System.out.println("MAIN_E");
    Thread.sleep(10);

  }
}

```

{% endcode %}

Nell'esempio sopra sono state aggiunte delle `Thread.sleep()` tra le diverse `println`, solo per aumentare il livello di concorrenza tra i thread e aumentare così la variabilità dell'output di esecuzione.

Esempi di output di due esecuzioni del programma `EsempioThreadMain`:

```
PS C:\SCUOLA\RUN> javac .\EsempioThreadMain.java
PS C:\SCUOLA\RUN> java EsempioThreadMain
MAIN_A
THREAD_A
MAIN_B
MAIN_C
THREAD_C
THREAD_D
MAIN_D
THREAD_E
MAIN_E
PS C:\SCUOLA\RUN> java EsempioThreadMain
MAIN_A
THREAD_A
THREAD_B
MAIN_B
THREAD_C
MAIN_C
MAIN_D
THREAD_D
THREAD_E
MAIN_E
PS C:\SCUOLA\RUN>
```

Notate che l'output dell'esecuzione non è deterministico.

> **DOMANDA**
>
> Se togliamo il commento all'istruzione `t1.join()` nel codice del `main` dell'esempio sopra (riga 31), qual è l'output dell'esecuzione?&#x20;
>
> Giustificate la vostra risposta.

### 2 - Creazione di thread contatore

Crea un'applicazione che abbia due contatori che in modo concorrente stampino a video il valore dalle propria variabile counter: uno parte da 0, poi 1, 2.... per 100 passi quindi fino a 99, l'altro contatore parte da 100, poi 101, 103 fino a 199 (sempre 100 passi). Facciamo inoltre che ogni contatore tra un numero e l'altro stampato a video, aspetti qualche centinaio di millisecondi, in modo da vedere meglio a video l'esecuzione contemporanea delle stampe a video dei due contatori e aumenti il livello di multiprogrammazione (suggerimento: utilizzate la `sleep` della classe `Thread`).&#x20;

&#x20;Qui lo pseudocodice del contatore:

```java
// Some code
/* 
startCounter variabile di tipo int che contiene il valore per iniziare
a contare.
100 sono i passi che compie il contatore dal punto di partenza.
*/

for (int i = startCounter; i < startCounter + 100; i++ ) {
    System.out.println(i);
    // sleep(400);
}

```

![Activity diagram - flusso esecuzione dell'applicazione](/files/PnhzUdqtqcyCzlVScYNn)

### 3 - Utilizzo di join

Fare un ulteriore versione che stampi un messaggio dal metodo `main` quando i due thread hanno finito di stampare l'incremento del progressivo. *Suggerimento: utilizzate il metodo `join` della classe `Thread` per sincronizzarsi con la fine dei due thread.*

![Activity diagram - flusso esecuzione dell'applicazione](/files/Ij0ABqGP9x8AUmIrq7mT)

### 4 - Numero contatori generico

Generalizzare l'applicazione dell'esercizio 2 affinché sia possibile da riga di comando passare il numero di contatori da creare e il *main thread* aspetti che tutti i contatori abbiano finito attraverso il metodo `join()` della classe `Thread`. Dopo che tutti i thread hanno finito scrive a video il messaggio *"FINE APPLICAZIONE"*.

### 5 - Interruzione di un thread in esecuzione

1. Scrivere un'applicazione che abbia un thread che in un ciclo infinito scriva a *standard outpu*t un numero random diverso ad ogni ciclo. Utilizzate la classe standard `java.util.Random` per generare numeri random:

```java
// Some code
long seed = System.currentTimeMillis();
Random random = new Random(seed);

// vedere ciclo infinito
while (true) {

	int randValue = random.nextInt(1000);
	System.out.println(randValue);

	Thread.sleep(400);

}		
		
```

Se dopo 10 secondi volessimo stopparlo come potremmo fare?&#x20;

Suggerimento: utilizzate il metodo `interrupt()` della classe `Thread`.

2\. Creare un'altra applicazione che prende da *standard input* il comando per stoppare l'applicazione quando lo desiderate.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://checksound.gitbook.io/corsojava/i-thread-e-concorrenza/esercizi-multithreading.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
