CIT 594 Assignment 9: Registration Madness
Spring 2013, David Matuszek
Purposes of this assignment
- Give you experience with Thread-based concurrency.
General idea of the assignment
Registration for courses at Wossamatta U. is done electronically. Because there is contention for the most desirable courses, the instant that registration opens, all the students try to register for courses. The lucky ones get all their courses; the very unlucky ones may not get any courses they want. However, there is enough room for all students to get the required three courses.
Your assignment is to write a complete simulation of 500 190 students trying to register for 24 offered courses. When the simulation is complete, print out some statistics about the result--how many students got their desired courses, etc. Also print out the total time that your program takes (should only be several seconds.)
Problem details
To avoid getting tangled up in a lot of "real life" details, we will assume a lot of uniformity. For example, all classrooms are the same size.
- There are 12 courses offered, and two sections (morning and afternoon) of each course, giving a total of 24 sections.
- The courses are numbered 101 through 112.
- There are no time conflicts among the courses.
- Every section has a limit of 25 students.
- Every student must take exactly three courses.
- No student may take both sections of the same course.
- Each student has a preference for either morning courses (p = 0.4) or afternoon courses (p = 0.6).
- Preferences are randomly set, so approximately 40% of the students prefer morning courses.
- There are 190 students.
- Each student has a unique student ID, which is a small positive integer (1, 2, 3, ..., 190).
Programming details
- Each section has a roster of registered students (maximum 25) and a waiting list (unlimited size).
- When a section receives a registration request from a student:
- If there is room in the roster, the student is registered (added to the roster), and a confirmation is sent to the student.
- If there is not room, the student is added to the waiting list (which is a queue), and the student is informed that the request failed.
- When a section receives a withdrawal request from a student:
- The student is removed from the roster (if present) or the waiting list (if present). No reply is sent to the student, as the withdrawal is guaranteed to succeed.
- If there is a waiting list, the student at the head of the list is removed from the list and registered (added to the roster). The student is informed.
- Each student has a list of three (randomly selected) courses that he/she wants to take.
- A student may take the following actions:
- Ask whether there is room in a given section (that is, the roster is not yet full).
- Try to register for a given section. This may or may not succeed.
- Withdraw from a given section (un-register, or remove from waiting list).
- Finish the registration process, if registered for exactly three courses and not on any waiting lists.
- A student who prefers morning courses will settle for the afternoon section of the same course, if that's all that's available.
- Similarly, students who prefer afternoon courses and can't get them will settle for the morning sections.
- Any student who cannot get their three desired courses must fill out their schedule with other courses.
- Just to "make things interesting" (ensure some concurrency), a student cannot perform actions (inquire, register, withdraw) faster than one per second. Use
Thread.sleep(1000).
- The simulation ends when all students have finished registering, and have the required three courses.
- When registration is complete, print out a selection of interesting statistics--how many students got a perfect schedule, how many students got all three desired courses, stuff like that. Also print out how long the simulation took to finish.
Thread pools
For this program, it makes sense to use a Thread for each student and a Thread for each section (190 threads). Since threads are expensive to create, it is probably better to use a smaller number of threads, and recycle them. Java provides a thread pool for this purpose. Here's a basic outline of how to use a thread pool:
-
import java.util.concurrent.Executors;
ExecutorService pool = Executors.newFixedThreadPool(poolSize);
- Create some
Runnable objects (objects that implement public void run())
pool.execute(Runnable object);
void shutdown() stops accepting new tasks.
List<Runnable> shutdownNow() stops all tasks and returns a list of unfinished tasks.
See Executor and ExecutorService in java.util.concurrent for more details.
Due date
Your program is due before 6am Thurdsay, April 25. Zip up the entire
directory for this project, and submit via Canvas.