Java 7: Multi-Threading
This week you will NOT need to submit your solutions.
- Create your repository: https://classroom.github.com/a/eHowHiLH
Objectives
- To understand how threads allow a program to multi-task
- To use threads for networking to prevent the program from blocking when trying to receive messages
Threads in Java
An example without threads
To see why threads are useful, let us first look at an example that does not use threads:
- We will simulate a dog-race viewed aerially: two lines that grow randomly across the screen until one reaches the end.
Look at Race1.java
program in the threads.dograce
package:
- If you run it you can see, it’s a very crude depiction of a dog-race
- Each dog sleeps for a random amount of time (Uniformly distributed in [300,600] milliseconds).
- After waking up, a dog runs for a random distance (Uniformly distributed in [50,100] pixels) and goes to sleep again.
Let us examine the code in more detail:
- The basic components of the frame are: two buttons and a canvas.
- Pressing the start button starts the race. (This is done in the method race()).
- Each Dog instance:
- Keeps track of its position.
- Generates the next position and draws the ground covered so far.
- The simulation keeps track of the “next event” (i.e., which dog wakes up next).
- In the while-loop of method race(), the method sleep() of Thread is used:
- sleep() is a static method of Thread.
- Any code can call sleep().
- The parameter is the number of milliseconds the current thread is put to sleep.
sleep() throws an exception and therefore requires a try-catch block.
- Just because we are calling Thread.sleep() does not mean that we are using threads.
- This just happens to be the class in which Java has placed the sleep() method.
- The sleep() method “pauses” the current execution for the specified time.
- Note something interesting (troubling) about our application: you cannot “quit” until the race is over:
- Thus, the event-handler for “quit” is not called until the race completes.
- This is not the kind of behavior one expects of a sophisticated application.
Exercise 1:
Race1.java
program in thethreads.dograce
package to:
- Each dog will run as a separate thread.
- Each such thread will sleep and move on its own.
- To create and use a thread, use the following steps:
- Decide which class is going to run as a thread (or which class has the “main-loop” of the thread).
- Make that class implement the Runnable interface.
- To implement this interface, the class has to implement a method called public void run().
- The run() method will be called when the thread is started.
- Next, to actually run the thread, pass the selected class to a new instance of Thread and call the start() method of the Thread instance.
The same example with threads
Look at Race2.java
program in the threads.dograce
package:
- The class Dog now implements the Runnable interface.
- The
run()
method of Dog contains the main loop for a single dog-thread: repeatedly sleep and move until the finish line is crossed. - Creating a thread is as simple as passing a Dog instance to the constructor of
Thread
:Thread dThread1 = new Thread (d1);
- To actually start the thread going, one calls the
start()
method of the thread instance:dThread1.start();
Note:
- Now you can “quit” the application during the race.
- Notice what happens when one dog wins: the other dogs complete the race.
Exercise 2:
Race2.java
program in thethreads.dograce
package solve the problem of “losers” continuing the race.
To do that have each thread should read the status of the race via a method call:
public boolean raceFinished (boolean set)
{
// If set==true, set the race to be over.
// Otherwise, return current status.
}
Thus, the same method is called by each dog to either (1) indicate that the race is over; or (2) find out whether the race is over.