Les persones treballadores de l'empresa informàtica s'han adonat que la faena de les persones
coordinadores (managers) només és assignar tasques i comprovar que s'han realitzat, i han
decidit prescindir-ne.
Per gestionar les tasques, cada equip Team ha creat una borsa de tasques que s'han de
realitzar. Cada persona empleada de l'equip agafa una tasca de la borsa i la realitza. Les
tasques han de passar per dos estats abans de considerar-se finalitzades.
Crea el programa CollectiveTasks que simule la realització d'un projecte en el qual
diferents equips realitzen les seues tasques sense necessitat de cap manager. Implementa els
mètodes següents:
Task::work(): defineix com es completa una tasca. Ha d'obtindre el fil actual i fer que
espere tants mil·lisegons com s'han definit en la tasca. A més, ha d'imprimir un missatge
quan comença la tasca i quan acaba:
Pere: Starting task Main page design...
Pere: Finished task Main page design (2500 ms).
Task::test(): defineix com es prova una tasca. Ha d'obtindre el fil actual i fer que
espere la meitat dels mil·lisegons definits en la tasca. A més, ha d'imprimir un missatge
quan comença la prova i quan acaba:
Pere: Testing task Main page design...
Pere: Finished testing task Main page design (1250 ms).
EmployeeThread::run(): defineix el comportament de cada persona empleada. Ha d'obtindre
la tasca següent a realitzar del seu equip Team:
Si la Task no està completada:
Realitzar la tasca amb Task::work().
Una vegada completada, afegir la tasca a Task::testingTasks.
Si la Task no està provada:
Provar la tasca amb Task::test().
Una vegada provada, afegir la tasca a Task::finishedTasks.
Si la Task és null: ja s'han completat totes les tasques.
A més, ha de mostrar un missatge amb la tasca obtinguda:
Pere: Assigned to task Main page design.
Pere: No more pending tasks. Going home.
Team::getNextTask(): retorna la tasca següent que ha de realitzar l'equip. Retorna la
primera tasca de unfinishedTasks. Si no en queden en aquesta llista, retorna la primera
tasca de testingTasks. Si no en queden en cap llista, retorna null.
CollectiveTasks::main(): crea els equips i les tasques. Cal completar-lo perquè cada
equip comence a treballar en les tasques assignades. Ha de mostrar el missatge següent quan
tots els equips acaben les seues tasques:
Project finished! Every team has finished the assigned tasks.
Utilitza monitors per controlar els accessos als recursos compartits.
Cal modificar les definicions dels mètodes sensibles a problemes de concurrència
utilitzant synchronized.
packageud2.practices.collectivetasks;publicclassCollectiveTasks{publicstaticvoidmain(String[]args){Teamfrontend=newTeam("Frontend");frontend.addTask("Main page design",2500);frontend.addTask("Shopping cart navigation bar",5500);frontend.addTask("Breadcrumb",1500);frontend.addTask("Profile page",7500);frontend.addEmployee(newEmployeeThread("Pere"));frontend.addEmployee(newEmployeeThread("Maria"));Teambackend=newTeam("Backend");backend.addTask("Connect API to database",3000);backend.addTask("Shopping API models",4200);backend.addTask("API authentication",2100);backend.addTask("Testing API",5500);backend.addEmployee(newEmployeeThread("Anna"));backend.addEmployee(newEmployeeThread("Arnau"));Teamdatabase=newTeam("Database");database.addTask("Relation Model",5000);database.addTask("Define models in the database",4200);database.addTask("Install DBMS",3000);database.addTask("Views",2800);database.addEmployee(newEmployeeThread("Mireia"));database.addEmployee(newEmployeeThread("Mar"));// TODO: Start all the teams and wait for them to finish their tasksSystem.out.println("Projecte acabat! Tots els equips han acabat les tasques assignades.");}}
Team.java
packageud2.practices.collectivetasks;importjava.util.ArrayList;importjava.util.List;publicclassTeam{privatefinalStringname;privatefinalList<EmployeeThread>employees;privatefinalList<Task>unfinishedTasks;privatefinalList<Task>testingTasks;privatefinalList<Task>finishedTasks;publicTeam(Stringname){this.name=name;employees=newArrayList<>();unfinishedTasks=newArrayList<>();testingTasks=newArrayList<>();finishedTasks=newArrayList<>();}publicStringgetName(){returnname;}publicList<EmployeeThread>getEmployees(){returnemployees;}publicvoidaddEmployee(EmployeeThreademployee){this.employees.add(employee);employee.setTeam(this);}publicvoidaddTask(StringtaskName,inttaskDuration){unfinishedTasks.add(newTask(taskName,taskDuration));}publicTaskgetNextTask(){/** * TODO: * Get next Task from unfinishedTasks. If all unfinishedTaks are done, * get next Task from testingTasks. * The task must be deleted from the list when retrieved. * If all Tasks are done and tested, return null. */returnnull;}}
EmployeeThread.java
packageud2.practices.collectivetasks;importjava.util.ArrayList;importjava.util.List;publicclassEmployeeThreadextendsThread{Teamteam;publicEmployeeThread(Stringname){super();this.setName(name);this.team=null;}publicvoidsetTeam(Teamteam){this.team=team;}@Overridepublicvoidrun(){/* * TODO: Get next task from team. * * If the task needs to be done: * - Do the task with work() * - Add the task to testingTasks * If the task needs to be tested: * - Test the task with test() * - Add the task to finishedTasks * If the task is null: * - All tasks are done. Exit. */System.out.printf("%s: Ha realitzat totes les tasques assignades.\n",this.getName());}}
Task.java
packageud2.practices.collectivetasks;publicclassTask{privatefinalintduration;privatefinalStringname;privateTaskStatusstatus;publicTask(Stringname,intduration){this.name=name;this.duration=duration;status=TaskStatus.UNFINISHED;}publicintgetDuration(){returnduration;}publicStringgetName(){returnname;}publicTaskStatusstatus(){returnstatus;}publicvoidsetStatus(TaskStatusstatus){this.status=status;}publicvoidwork(){Threadcurrent=Thread.currentThread();System.out.printf("%s: Starting task %s...\n",current.getName(),this.name);// TODO: Do the task (sleep DURATION miliseconds)setStatus(TaskStatus.TESTING);System.out.printf("%s: Finished task %s (%d).\n",current.getName(),this.name,this.duration);}publicvoidtest(){Threadcurrent=Thread.currentThread();System.out.printf("%s: Starting task %s...\n",current.getName(),this.name);// TODO: Do the task (sleep DURATION / 2 miliseconds)setStatus(TaskStatus.FINISHED);System.out.printf("%s: Finished task %s (%d).\n",current.getName(),this.name,this.duration);}}
Crea el programa SwimmingPool que simule una piscina pública, on diferents persones poden
accedir als recursos de la piscina simultàniament. Els recursos disponibles són:
Una piscina amb capacitat per a 10 persones.
Dutxes amb capacitat per a 3 persones.
Una zona per descansar.
Cada persona s'executa en un fil diferent i realitza les accions següents, que es repeteixen
indefinidament:
El programa principal ha d'esperar 1 minut i interrompre l'execució de totes les persones.
Quan una persona canvie d'estat respecte a les accions anteriors, s'han de mostrar els
missatges següents:
packageud2.practices.swimmingpool;importjava.util.ArrayList;importjava.util.List;publicclassSwimmingPool{// TODO: Add semaphorespublicSwimmingPool(intpoolCapacity,intshowersCapacity){// TODO: Create semaphores}// TODO: create get() method for semaphorespublicstaticvoidmain(String[]args){SwimmingPoolpool=newSwimmingPool(10,3);String[]names={"Andrès","Àngel","Anna","Carles","Enric","Helena","Isabel","Joan","Lorena","Mar","Maria","Marta","Míriam","Nicolàs","Òscar","Paula","Pere","Teresa","Toni","Vicent"};List<PersonThread>persons=newArrayList<>();for(Stringname:names){// TODO: Create the threads and start them}// TODO: Wait 60 seconds and kick all persons// TODO: Wait for all persons to leaveSystem.out.println("Tothom ha marxat de la piscina.");}}
PersonThread.java
packageud2.practices.swimmingpool;publicclassPersonThreadextendsThread{privatefinalSwimmingPoolpool;publicPersonThread(Stringname,SwimmingPoolpool){super(name);this.pool=pool;}/** * TODO: The persons rests between 1 and 5 seconds * @throws InterruptedException: if the thread is interrupted */publicvoidrest()throwsInterruptedException{intmilis=0;System.out.printf("%s està descansant %.2f segons.\n",getName(),milis/1000.0);}/** * TODO: The persons takes a shower for 2 seconds * - Tries to get into a shower * - Takes a shower * - Leaves the showers * @throws InterruptedException: if the thread is interrupted */publicvoidtakeShower()throwsInterruptedException{intmilis=2000;System.out.printf("%s vol dutxar-se.\n",getName());System.out.printf("%s està dutxant-se.\n",getName());System.out.printf("%s ha acabat de dutxar-se.\n",getName());}/** * TODO: The persons swims between 1 and 10 seconds * - Tries to get into the swimming pool * - Swims * - Leaves the swimming pool * @throws InterruptedException: if the thread is interrupted */publicvoidswim()throwsInterruptedException{intmilis=0;System.out.printf("%s vol nadar.\n",getName());System.out.printf("%s està nadant %.2f segons.\n",getName(),milis/1000.0);System.out.printf("%s ha eixit de la piscina.\n",getName());}@Overridepublicvoidrun(){while(true){// TODO: Rests// TODO: Takes a shower// TODO: Swims}// System.out.printf("%s ha abandonat les instal·lacions.\n", getName());}}
Crea el programa LyricsApp, un reproductor de lletres de cançons que simula com treballen
els reproductors de música. El programa ha de crear dos fils diferents:
Player: reprodueix la cançó escollida. El reproductor mostra una paraula de la lletra
cada mig segon (0,5 s).
Loader: s'encarrega de descarregar la cançó en segon pla. Aquest fil llig les lletres
des del fitxer de text
files/ud2/lyrics.txt.
El programa ha de seguir l'estructura bàsica de Producer/Consumer:
El fil Loader obté les línies del fitxer i les guarda en la llista de línies.
El fil Player obté les línies a mostrar a partir de la llista LyricsApp::lines i les
mostra per pantalla.
Crea els mecanismes de sincronització necessaris perquè:
El fil Player espere que hi haja alguna línia disponible per poder reproduir-la.
El fil Loader notifique que ha llegit una línia.
No hi haja accessos simultanis a la llista LyricsApp::lines.