In the previous lesson we saw how to use Map.
Multithreading
Threads allow your application to perform more than one process concurrently.
In this section you will learn:
- The principles of multi-threading
- Extending the
Threadclass - Implementing the
Runnableinterface - Using
wait()andnotifyAll()to coordinate dependent threads
The principles of multi-threading
You will probably be familiar with the idea of multi-tasking, whereby one computer is able to run more than one application at the same time. For example, on a desktop system you might have a word processor, a browser, and an email application open and operating concurrently. Even if the desktop system in question only has a single physical processor as part of its hardware, it is still able to give the appearance of multi-tasking by rapidly and automatically switching between them under the control of the operating system.
Multi-threading is a similar concept except that it refers to a single application being able to run multiple processes concurrently, or at least give the appearance of doing so. This can be a very useful feature for certain types of application:
- A "space invaders" style game needs to move aliens across the screen and at the same time be able to respond to your keyboard and mouse clicks to fire ammunition at the aliens
- A browser needs to be able to download a movie file while still letting you browse to other sites on a different tab
- A bank needs to be able to serve its ATM machines around the country
In all the above cases, and many more, each of the activities that needs to run independently is defined in the software as a separate thread. A thread is therefore a single line of execution that can run concurrently with one or more other threads. In the case of Java, it is the JVM that takes care of the switching between separate threads. It does so by giving each thread a small amount of time to do some processing before pausing it and then giving time to some other thread. The Garbage Collector, mentioned in Section 4, runs in its own thread.
It is worth bearing in mind that all Java applications run in at least one thread automatically. When you code your own threaded classes, you are adding additional threads to it.
An example multi-threaded scenario
Suppose the zoo requires a facility to allow entry tickets to be booked in advance, and that there could be multiple persons trying to make bookings at the same time, such as through an online booking system. You would therefore have a single object of type BookingCounter (to be created shortly) and multiple objects of type Booker (also to be created shortly) each of which is an individual thread.
Here is the BookingCounter class, which simply keeps a count of the number of bookings made. Create this class in the virtualzoo.core package:
package virtualzoo.core;
public class BookingCounter {
private int count;
public BookingCounter() {
count = 0;
}
public int getCount() {
return count;
}
public void makeBooking() {
// Get copy of the current count
int copyCount = count;
// Add one to the count copy
copyCount++;
// Sleep for 1 millisecond to allow another thread to run
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
// Update the actual count from the copy
count = copyCount;
}
}
- The class contains a single instance variable called
countto keep a count of how many bookings have been made. The constructor initialises this to zero - The
getCount()method just returns the current value of count - The
makeBooking()method increments the count by one. The code to do so has been made more complex than it needs to be to demonstrate a problem that can and will occur with multi-threaded code. TheThread.sleep()method call causes the current thread to sleep for the number of milliseconds specified in the argument. This has been used here to effectively force the JVM to give time to a different thread, if there are any.
You now need to define a multi-threaded class to represent persons making a booking. There are two ways in which you can make objects of a class capable of being executed concurrently: by extending the Thread class or by implementing the Runnable interface[1].
In the next lesson we will show how to extend the Thread class.
Comments