CPSC 2800 Final Project This project can be completed in lieu of taking the final exam. All parts should be completed in Java. You should submit your source code along with a report including screenshots and explanations of each portion. Part One Implement a solution to the readers-writers problem described in sections 6.6.2 and 6.8.3. When your program starts, it should prompt the user for the number of readers and the number of writers in your system. Your program should create a thread for each reader and each writer, each with a unique identifier (id number). All your threads want to access one common object (for instance, a Character object). When readers access it, they should print "Reader <id> read <value>." When writers access the object, they should change it to a different (random) value, and print "Writer <id> wrote <value>." Once a reader has read the value, it should sleep for some random period of time (e.g. 0.5-2 seconds). The same goes for writers after they have written. Part Two Implement a multithreaded program in which deadlock occurs. Part Three Implement a solution to the Sleeping-Barber problem (6.44, page 308). Part Four Implement a solution to the Baboon Crossing problem. A canyon cuts through the territory of a colony of baboons. The baboons use a rope stretching across the canyon to cross from one side to the other. The rope is strong enough to permit any number of baboons to cross in the same direction at the same time. However, the rope is too thin for the baboons to cross the canyon in both directions at the same time. Consequently, a baboon that wants to cross from west to east must wait until all westward-moving baboons have finished crossing and the rope is free. Your implementation should create new baboons to cross the rope at random. Your solution should not allow starvation. Part Five Implement a CPU scheduling algorithm simulator. Your solution should first generate some random "processes," each with a random run time and random arrival time (time from 0). Then you should simulate running the tasks using the FCFS and Round Robin scheduling algorithms. Your program should output the stats for each (average wait time and average turnaround time). Example output (using FCFS): Allowing task 0 to run at time 0.0 Task 0 running for 11.512414188771066 time units. (0.0 left.) ... This task has waited for 0.0 time units so far. Task 0 has FINISHED! (TurnAround time was 11.512414188771066). Allowing task 1 to run at time 11.512414188771066 Task 1 running for 0.19535986859555043 time units. (0.0 left.) ... This task has waited for 11.431520467106587 time units so far. Task 1 has FINISHED! (TurnAround time was 11.626880335702138). Allowing task 2 to run at time 11.707774057366617 Task 2 running for 0.2792671749155562 time units. (0.0 left.) ... This task has waited for 9.415498166712547 time units so far. Task 2 has FINISHED! (TurnAround time was 9.694765341628104). .... Stats: Average wait time: 4.42797785215895 Average turnaround time: 5.835190638467456