Els treballadors de l'empresa informàtica s'han adonat que la faena
dels Managers sols és assignar tasques als treballadors i comprovar
que s'han realitat, i han decidit prescindir d'ells.
Per gestionar les tasques, cada equip Team ha creat una borsa de tasques
que s'han de realitzar. Cada empleat de l'equip agafarà una tasca de la borsa
i la realitzarà. Les tasques han de passar per dos estats abans de
assignar-les com finalitzades.
Crea el programa CollectiveTasks que simule la realització d'un projecte
on diferents equips realitzen les seues tasques sense necessitat de cap manager.
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 mil·lisegons com s'ha definit en la tasca.
Aquest mètode imprimirà un missatge quan comence la tasca i
quan es finalitze:
Pere: Starting task Main page design...
Pere: Finished task Main page design (2500 ms).
Task::test(): Aquest mètode defineix com es prova una
tasca. Aquest mètode ha d'obtenir el fil actual i fer que
espere la meitat de mil·lisegons com s'ha definit en la tasca.
Aquest mètode imprimirà un missatge quan comence la tasca i
quan es finalitze:
Pere: Testing task Main page design...
Pere: Finished testing task Main page design (1250 ms).
EmployeeThread::run(): Aquest mètode defineix el comportament de
cada treballador. Aquest mètode obtindrà la següent tasca 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 completada, afegir la tasca a Task::finishedTasks
Si la Task és null:
Ja s'han completat totes les tasques.
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(): Aquest mètode retorna la següent tasca
que l'equip ha de realitzar.
Retornarà la primera tasca de unfinishedTasks. Si no queden
tasques en aquesta llista, retornarà la primera tasca de testingTasks.
Si no queden tasques en cap llista, retornarà null.
CollectiveTasks::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:
Project finished! Every team has finished the assigned tasks.
Important
S'han d'utilitzar monitors per controlar els accessos a recursos
compartits. Cal modificar les definicions dels mètodes sensibles a
problemes per concurrència, utilitzant syncronized.
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);}}
packageud2.practices.collectivetasks.solution;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 tasksfrontend.getEmployees().forEach(Thread::start);backend.getEmployees().forEach(Thread::start);database.getEmployees().forEach(Thread::start);try{for(EmployeeThreade:frontend.getEmployees()){e.join();}for(EmployeeThreade:backend.getEmployees()){e.join();}for(EmployeeThreade:database.getEmployees()){e.join();}}catch(InterruptedExceptione){System.err.println("Error: "+e.getMessage());}System.out.println("Projecte acabat! Tots els equips han acabat les tasques assignades.");}}
Team.java
packageud2.practices.collectivetasks.solution;importjava.util.ArrayList;importjava.util.List;publicclassTeam{privateStringname;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){synchronized(unfinishedTasks){unfinishedTasks.add(newTask(taskName,taskDuration));}}publicTaskgetNextUnfinishedTask(){synchronized(unfinishedTasks){if(unfinishedTasks.isEmpty()){returnnull;}returnunfinishedTasks.removeFirst();}}publicvoidaddTestingTask(Taskt){synchronized(testingTasks){testingTasks.add(t);}}publicTaskgetNextTestingTask(){synchronized(testingTasks){if(testingTasks.isEmpty()){returnnull;}returntestingTasks.removeFirst();}}publicvoidaddFinishedTask(Taskt){synchronized(finishedTasks){finishedTasks.add(t);}}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. */Taskt=getNextUnfinishedTask();if(t==null)t=getNextTestingTask();returnt;}}
EmployeeThread.java
packageud2.practices.collectivetasks.solution;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. */try{Taskt=team.getNextTask();while(t!=null){if(t.status()==TaskStatus.UNFINISHED){t.work();team.addTestingTask(t);}elseif(t.status()==TaskStatus.TESTING){t.test();team.addFinishedTask(t);}t=team.getNextTask();}System.out.printf("%s: Ha realitzat totes les tasques assignades.\n",this.getName());}catch(InterruptedExceptione){System.err.println("Error: "+e.getMessage());}}}
Task.java
packageud2.practices.collectivetasks.solution;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()throwsInterruptedException{Threadcurrent=Thread.currentThread();System.out.printf("%s: Starting task %s...\n",current.getName(),this.name);// TODO: Do the task (sleep DURATION miliseconds)Thread.sleep(this.duration);setStatus(TaskStatus.TESTING);System.out.printf("%s: Finished task %s (%d).\n",current.getName(),this.name,this.duration);}publicvoidtest()throwsInterruptedException{Threadcurrent=Thread.currentThread();System.out.printf("%s: Starting task %s...\n",current.getName(),this.name);// TODO: Do the task (sleep DURATION / 2 miliseconds)Thread.sleep(this.duration/2);setStatus(TaskStatus.FINISHED);System.out.printf("%s: Finished task %s (%d).\n",current.getName(),this.name,this.duration/2);}}
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());}}
packageud2.practices.swimmingpool.solution;importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.Semaphore;publicclassSwimmingPool{// TODO: Add semaphoresprivatefinalSemaphorepoolSemaphore;privatefinalSemaphoreshowersSemaphore;publicSwimmingPool(intpoolCapacity,intshowersCapacity){// TODO: Create semaphorespoolSemaphore=newSemaphore(poolCapacity);showersSemaphore=newSemaphore(showersCapacity);}// TODO: create get() method for semaphorespublicSemaphoregetPoolSemaphore(){returnpoolSemaphore;}publicSemaphoregetShowersSemaphore(){returnshowersSemaphore;}publicstaticvoidmain(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){PersonThreadp=newPersonThread(name,pool);persons.add(p);p.start();}try{// TODO: Wait 60 seconds and kick all personsThread.sleep(60000);// TODO: Wait for all persons to leavefor(PersonThreadp:persons){p.join();}}catch(InterruptedExceptione){System.err.println("Error: "+e.getMessage());}System.out.println("Tothom ha marxat de la piscina.");}}
PersonThread.java
packageud2.practices.swimmingpool.solution;importjava.util.concurrent.ThreadLocalRandom;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=ThreadLocalRandom.current().nextInt(1000,5000);System.out.printf("%s està descansant %.2f segons.\n",getName(),milis/1000.0);Thread.sleep(milis);}/** * 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());pool.getShowersSemaphore().acquire();System.out.printf("%s està dutxant-se.\n",getName());Thread.sleep(milis);pool.getShowersSemaphore().release();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=ThreadLocalRandom.current().nextInt(1000,10000);System.out.printf("%s vol nadar.\n",getName());pool.getPoolSemaphore().acquire();System.out.printf("%s està nadant %.2f segons.\n",getName(),milis/1000.0);Thread.sleep(milis);System.out.printf("%s ha eixit de la piscina.\n",getName());pool.getPoolSemaphore().release();}@Overridepublicvoidrun(){try{while(!isInterrupted()){// TODO: Restsrest();// TODO: Takes a showertakeShower();// TODO: Swimsswim();}}catch(InterruptedExceptione){System.out.printf("%s interromput.\n",getName());}System.out.printf("%s ha abandonat les instal·lacions.\n",getName());}}