CSC 125/259 Java Programming Assignment 1 Please submit your program on blackboard in three separate files, one for each problem. Please observe the usual rules of good programming, including meaningful comments and indentation. You may use an IDE or just type the program using some editor suitable for programming, such as notepad++ or emacs. --- 1. (warm up) Create a program with two threads. The first one should repeatedly execute: System.out.print("a"); System.out.flush(); // flush OS print buffer System.out.print("a"); System.out.flush(); and the second thread should repeatedly execute: System.out.print("b"); System.out.flush(); // flush OS print buffer System.out.print("b"); System.out.flush(); You may structure your program in several ways: a. Create one Runnable class and instance; the other thread is main b. Create two separate Runnable classes c. Create one Runnable class with two different instances. I recommend the c. option. Create a class with instance variables that control the variation. 1b. modify the class(es) to allow it to loop a finite number of times. The number is be passed in as a parameter. 1c. Protect the print statements in each thread as a critical section Using the semaphore mechanism (find implementation on blackboard, lesson 4, or re-implement it yourself). ------------ 2. I want to write a program that simulates a shared bank account. See the attached file banking.java. The account class is a very ordinary class. There are two thread classes: spender and earner (both inherit from a superclass that implements what they have in common). The earner deposits and the spender withdraws from the shared account. Study this program to make sure you understand how it works. In main, one earner and two spender threads are created. Clearly, there's a problem with lack of synchronization. The balance variable could be read and modified by different threads at the same time. For example, you can varify that amt<=balance, but before you withdraw another spender thread could have decreased the balance! 2a. Your first task is to protect access to the balance variable as a critical section. This should be simple enough. Since none of the account methods require much computation, you can go ahead and make them all synchronized methods. 2b. The earner can never earn as fast as the spenders can spend, but fortunately the bank does not allow overdraws (see withdraw method). However, instead of rejecting the transaction right away, we would like to have the spender thread *wait until enough funds are available*. As soon as a new deposit is made, the suspended threads can attempt their transactions again. Please implement this refinement. Demonstrate that it works. You may change the run() methods of the thread classes and create other instances. Use the printbalance() method and further delays to trace your program. Extra mechanism you can use in your program: Given a thread object t1, you can call t1.interrupt(); to send an interrupt signal to the thread. If the thread is currenting wait()ing, it will cause an InterruptedException to be thrown, which you will need to catch anyway. Consult the Java API (see online resources on blackboard) for other thread operations : heed the warning concerning Thread.destroy, however. 2c. You're a spender thread on a shopping spree (Fall Special!) and you need to make the following transactions: A.withdraw(500); A.withdraw(100); A.withdraw(200); Let's say the starting balance is only $200. You can't make the first withdraw and, assuming that part 2b has been implemented, you'll be stuck until the earner deposits enough money. This is not acceptable to a hard working spender like you. Instead of waiting, you SHOULD be allowed to make the second transaction first, A.withdraw(100). The first withdraw would still be pending, but you can go on with at least some of your shopping. In other words, you want to make withdraw as *non-blocking* operation. Please provide a solution. Explain your design carefully in comments. To design a complete solution, when your program ends there should not be any pending withdraws. Any thread that is wait()ing for funds to arrive should be interrupted via Thread.interrupt. The exception handler (catch) should then terminate the transaction and print out an appropriate trace message. To do this, you should keep track of all transaction threads in a data structure, e.g: import java.util.*; ... ArrayList WL = new ArrayList(); ... WL.add(new Thread(...)); ... for(Thread t:WL) t.interrupt(); Warning: Although this problem looks like an Ada program that I've posted, it is not advisable to duplicate the Ada code. Instead, formulate the Java solution from scratch. One does not normally simulate low-level devices using high-level constructs: it should be the other way around! ---------------- 3. Microsoft's Win32 API (for the native OS, not .Net) contains a thread-synchronization mechanism similar to the ones we've studied (such as semaphore). It's called an "Event". An event is either in a signaled or non-signaled state (initially non-signaled). Given an event object called event0, here are the operations that can be called on the event: event0.Lock(); // blocks calling thread IF event is in non-signaled state; // If event is in the signaled state, this will have no effect. event0.SetEvent(); // sets the event to the signaled state and releases // ALL blocked threads. event0.ResetEvent(); // sets the event back to the non-signaled state event0.PulseEvent(); // releases one blocked thread then immediately sets // the event back to the non-signaled state. Your assignment is to duplicate the Event synchronization mechanism in Java using a monitor. Note that if some precise behavior is not specified above (by the API), then you are free to decide on a reasonable behavior. Demonstrate your implementation with at least THREE threads. Be inventive. Make sure that each operation is meaningfully tested. *********** General hint: for PulseEvent, the best way to implement the behavior is to use conventional variables and boolean conditions. Try to MINIMIZE the reliance of your solution on language-specific features. ***********