Title: Project 2: An Application Employing Synchronized/Cooperating Multiple Threads In Java Using Locks A Banking Simulator
Objectives: To practice programming cooperating, synchronized multiple threads of execution.
Description: In this programming assignment you will simulate the deposits and withdrawals made to a fictitious bank account (Ill let you use my real bank account if you promise to make only deposits! J). In this case the deposits and withdrawals will be made by synchronized threads. Synchronization is required for two reasons (1) mutual exclusion (updates cannot be lost) and (2) because a withdrawal cannot occur if the amount of the withdrawal request is greater than the current balance in the account. This means that access to the account (the shared object) must be synchronized. This application requires cooperation and communication amongst the various threads (cooperating synchronized threads). (In other words, this problem is similar to the producer/consumer problem where there is more than one producer and more than one consumer process active simultaneously.) If a withdrawal thread attempts to withdraw an amount greater than the current balance in the account then it must block itself and wait until a deposit has occurred before it can try again. As we covered in the lecture notes, this will require that the deposit threads signal all waiting withdrawal threads whenever a deposit is completed.
- To keep things relatively simple, as well as to see immediate results from a series of transactions (deposits and withdrawals), assume that deposits are made in amounts ranging from $1 to $250 (whole dollars only) and withdrawals are made in amounts ranging from $1 to $50 (again, whole dollars only).
- You should have four deposit threads and eight withdrawal threads simultaneously executing.
- Once a deposit thread has executed, put it to sleep for few milliseconds (randomly generate this number dont use a constant sleep time) or so (depends a little bit on the speed of your system as to how long you will want to sleep the depositor threads basically we want to ensure a lot more withdrawals than deposits) to allow other threads to execute. This is the only situation in which a deposit thread will block.
- For withdrawal threads, things will be a bit different depending on whether you are working on a single or multi-core processor.
- For single core processors, once a withdrawal thread has executed, have it yield to another thread. Since the thread is giving up the processor voluntarily, it will be unlikely to run again (attempt a second withdrawal in a row), before another thread runs. Note however, that it does not prevent it from running again, if all other withdrawal threads are blocked and all depositors are sleeping, it will run again.
- For multi-core processors, once a withdrawal thread has executed, have it sleep for some random period of time (again, a few milliseconds should be fine). Depending on which core a thread is executing, yielding the CPU wont ensure that the same thread will not run again immediately. While, sleeping the thread will also not ensure that it will not run two or more times in succession, it is less likely to do so in the multi-core environment.
- What we dont want to happen is a single withdrawal thread gaining the CPU and then executing a long sequence of withdrawal operations. Recall though that withdrawal threads block if they attempt to withdraw more than the current balance in the account.
- Similarly, we dont want depositor threads monopolizing the CPU either and causing the balance in the account to grow continuously. This would most likely occur when the withdrawal threads are sleeping too long in comparison to the average sleep time of the deposit threads. See page 7 for an illustration of this.
- Assume all threads have the same priority. Do not give different priority to depositor and withdrawal threads.
- The output from your program must look reasonably similar to the sample output shown below.
- Do not put the threads into a counted loop for your simulation. In other words, the run() method should be an infinite loop. Just stop the simulation from your IDE after a few seconds.
- Do not use the Java synchronized statement. I want you to handle the locking and signaling yourself. No monitors!
- You must utilize a reentrant lock from the java.util.concurrent.locks package for implementing your locking protocols. We will specify no fairness policy for this application. Do not create your own lock using a Boolean or any other type of variable.
References:
Notes: Lecture Notes for Multithreaded Applications.
Restrictions:
Your source files shall begin with comments containing the following information:
/* Name:
Course: CNT 4714 Fall 2019
Assignment title: Project 2 Synchronized, Cooperating Threads Under Locking Due Date: October 6, 2019
*/
Input Specification: Internal to the program.
Output Specification: Console based. Your output should appear reasonably
similar to the output shown below.
Deliverables:
- Zip up all of your .java files and submit them via WebCourses no later than 11:59pm Sunday October 6, 2019.
- Include at least one screen shot which illustrates the execution of your synchronized threaded application. See below for some representative examples. You can either do a screen shot of the console window like I did below or redirect your output to a file and take a screen shot from an editor.
Additional Information:
Shown below are three example screen shots of the output from this program to help illustrate how your application is to operate and display the results. The last page illustrates execution runs that you do not want to produce.
We dont want to see this sort of scenario where the depositors are monopolizing the account. Indication is the depositor threads arent sleeping long enough.
Reviews
There are no reviews yet.