<div class="page"> <div class="cover text-center"> <img class="mx-auto" src=/itb/images/logo_mislata.png alt="logo"> # Creació de fils <div class="text-end fit-content ms-auto my-3 mt-auto pt-3"> <p><strong>Autor:</strong> Joan Puigcerver Ibáñez</p> <p><strong>Correu electrònic:</strong> j.puigcerveribanez@edu.gva.es</p> <p><strong>Curs:</strong> 2024/2025</p> </div> <div> <p class="fw-bold mb-0">Llicència: BY-NC-SA</p> <p class="d-none d-md-block">(Reconeixement - No Comercial - Compartir Igual)</p> <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ca" target="_blank"> <img class="mx-auto" src="/itb/images/license.png" alt="Licence"/> </a> </div><!--license--> </div><!--cover--> </div><!--page--> {:toc} # Objectius Conèixer i implementar programes que creen diferents fils d'execució. Tots els exercicis han d'estar situats en el package corresponent. - __Package:__ ud2.exericises - El nom de la classe de cada exercici és el nom. - El format de la eixida del programa ha de ser consistent amb el format demanat. ## ALotOfThreads Crea un programa que demane a l'usuari un nombre enter cree aquest nombre de fils. Cada fil ha de fer: - Mostrar un missatge quan comença la seua execució. - Esperar-se $N$ segons per acabar, on $N$ és l'identificador del fil, assignat per ordre de creació. (El primer esperarà 1 segon, el segon esperarà 2 segons, ...) - Podeu utilitzar el mètode [`Thred.sleep()`](https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#sleep(long)) - Missatge com que esta a punt d'acabar. > En els dos missatges ha d'apareixer el nom del fil, que s'assignarà > per ordre de creació (FIL1, FIL2, ...) ### Entrada ```text Introdueix els nombre de threads a crear: 3 ``` ### Eixida ```text Començant a calcular... FIL1: Comença execució. FIL2: Comença execució. FIL3: Comença execució. FIL1: Acaba execució. FIL2: Acaba execució. FIL3: Acaba execució. ``` ## FibonnaciConcurrent Crea el programa __FibonnaciConcurrent__ que vaja demanant numeros enters i naturals (majors de 0) a l'usuari. El programa deixarà de demanar números a l'usuari quan s'introduisca un 0. (Utilitzar nombre majors de 40 pot resultar en un overflow de el tipus de dades `int`, podeu utilitzar `long`). Per cada número introduït, el programa llançarà un fil que calcule els N primers nombres de [Succeció de Fibonnacci](https://ca.wikipedia.org/wiki/Successi%C3%B3_de_Fibonacci) i els mostrarà per pantalla. ### Entrada ```text Introdueix els nombres a calcular: 1 5 30 40 0 ``` ### Eixida ```text Començant a calcular... FIL1: Pas 1 de 1: 0 FIL2: Pas 1 de 5: 0 FIL2: Pas 2 de 5: 1 FIL3: Pas 1 de 30: 0 FIL2: Pas 3 de 5: 1 ... ... FIL2: Pas 5 de 5: 3 FIL3: Pas 30 de 30: 832040 FIL4: Pas 40 de 40: 102334155 ``` ## RunCounterThreads Crea el programa __RunCounterThreads__, que llance 4 instàncies de __CounterThread__, un fil que pot comptar desde un nombre inicial a un nombre final. - __Thread 1__: Compta de 1 al 10 en 1s de delay. - __Thread 2__: Compta de 10 al 100 en 0.1s de delay. - __Thread 3__: Compta de 25 al 50 en 0.4s de delay. - __Thread 4__: Compta de 1 al 5 en 1.3s de delay. Cada Thread ha de mostrar el següent missatge: ``` NOM_DEL_THREAD: comptador ``` ### Eixida ```text FIL1: 1 FIL2: 10 FIL2: 11 FIL3: 25 FIL2: 12 FIL4: 1 ... ... ``` ## InterruptCounterThreads Crea el programa __InterruptCounterThreads__, que llance 4 instàncies de __CounterThread__, un fil que pot comptar desde un nombre inicial i no deixarà mai de comptar. - __Thread 1__: Compta a partir del 1 en 1s de delay. - __Thread 2__: Compta a partir del 10 en 0.1s de delay. - __Thread 3__: Compta a partir del 25 en 0.4s de delay. - __Thread 4__: Compta a partir del 1 en 1.3s de delay. Cada Thread ha de mostrar el següent missatge: ``` NOM_DEL_THREAD: comptador ``` El programa principal comprovarà les següents condicions, i interrompre a cada Thread quan es complisca: - __Thread 1__: Haja comptat fins al 10. - __Thread 2__: Haja comptat fins al 50. - __Thread 3__: Hagen passat 3 segons. - __Thread 4__: Haja comptat 10 numeros després que el primer Thread haja acabat. Quan s'interromp un Thread, ha de mostrar el nom i el comptador. ``` NOM_DEL_THREAD interromput: comptador ``` ## SumMatrix - __Package:__ ud2.exercises.summatrix Crea el programa __SumMatrix__ que sume tots els valors d'una matriu d'enters utilizant un thread per sumar cada fila. Els valos d'aquesta matriu están en [data_matrix.csv](/itb/DAM-PSP/files/files/ud2/data_matrix.csv). Per llegir els valors d'aquest fitxer podeu utilitzar els següent mètode: ```java public static List<List<Integer>> readMatrixFromCSV(String path) { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.lines() .map( x -> Arrays.stream(x.split(",")) .mapToInt(Integer::parseInt) .boxed() .toList() ).toList(); } catch (Exception e) { System.out.printf("Error reading CSV file: %s\n", path); } return null; } public static void main(String[] args) { String CSVPath = "files/ud2/data_matrix.csv"; List<List<Integer>> matrix = readMatrixFromCSV(CSVPath); // TODO for(List<Integer> row : matrix){ // TODO: Create thread // TODO: Start thread } // TODO: Wait for the threads to finish // TODO: Sum the result of each thread System.out.printf("La suma dels valors en \"%s\" és %d\n", CSVPath, result); } ``` Heu de crear la classe __SumIntegerListThread__, que reba per paràmetre un `List<Int>` i que sume tots els valors d'aquesta llista en el mètode `void run()`. Aquesta classe hauria de tindre un atribut `int result` on se guardarà el resultat de la suma de la llista. El programa principal __SumMatrix__, ha de crear un `SumIntegerListThread` per cada fila de la matriu i llançar els threads. Quan tots els threads acaben de sumar la seua fila, el fil principal sumarà el resultat de cada fil i mostrarà el resultat. ### Eixida ``` La suma dels valors en "files/ud2/data_matrix.csv" és ????? ``` Apareixerà la suma en compte de `?????`. ## ManagerTasks - __Package:__ ud2.exercises.tasks El programa __ManagerTasks__ simula la realització d'un projecte on es coordinen diferents equips de desenvolupament. El fil principal crea 3 equips, cadascun d'ells liderats per un `ManagerThread`. Cada equip té uns empleats `EmployeeThread`, als quals se'ls han assignat unes tasques. S'han d'implementar els següents mètodes: - `Task::work()`: Aquest mètode defineix com es completa una tasca. Aquest mètode ha d'obtenir el fil actual i fer que espere tants milisegons com s'ha definit en la tasca. Aquest mètode imprimirà un missatge quan comence la tasca i quan es finalitze: ```text Pere: Starting task Main page design... Pere: Finished task Main page design (2500 ms). ``` - `EmployeeThread::run()`: Aquest mètode defineix el comportament de cada treballador. Aquest mètode realitzarà totes les tasques que el treballador té assignades. Quan acabe totes les tasques, mostrarà el missatge: ```text Pere: Ha realitzat totes les tasques assignades. ``` - `ManagerThread::run()`: Aquest mètode defineix el comportament del coordinador de l'equip. Aquest mètode posarà a tots els treballador de l'equip a realitzar les seues tasques i esperarà a que les finalitzen. Quan tots els treballadors de l'equip acaben les tasques, mostrarà el missatge: ```text FrontendManager: L'equip Frontend ha realitzat totes les tasques. ``` - `ManagerTasks::main()`: Aquest mètode crea els equips i les tasques, cal acabar-lo perquè cada equip comence a treballar en les tasques assignades. Mostrarà el següent missatge quan tots els equips acaben les seues tasques: ```text Projecte acabat! Tots els equips han acabat les tasques assignades. ``` ### Source code - <a href="/itb/DAM-PSP/files/ud2/exercises/tasks/ManagerTasks.java" download="ManagerTasks.java">ManagerTasks.java</a> - <a href="/itb/DAM-PSP/files/ud2/exercises/tasks/ManagerThread.java" download="ManagerThread.java">ManagerThread.java</a> - <a href="/itb/DAM-PSP/files/ud2/exercises/tasks/EmployeeThread.java" download="EmployeeThread.java">EmployeeThread.java</a> - <a href="/itb/DAM-PSP/files/ud2/exercises/tasks/Team.java" download="Team.java">Team.java</a> - <a href="/itb/DAM-PSP/files/ud2/exercises/tasks/Task.java" download="Task.java">Task.java</a>