THE UNIVERSITY OF WESTERN AUSTRALIA

Department of Computer Science

230.304 CONCURRENT PROGRAMMING

Laboratory Sheet 2 (for laboratories during week 4)

In the previous laboratory, you have learnt how to create multiple threads in a Java program through extending the Thread class. Though this is quite useful, you may not want to do this in some applications. You may lose some freedom in designing your code by having your class a subclass of the Thread class. In this laboratory, we will learn an alternative method for creating threads.

The purpose of this laboratory is to :

The Second Approach for Multithreading

You have already created multiple threads by extending the java.lang.Thread class. The class you created was below the Thread class in the class-hierarchy. However, in the following approach, we need not do this and our class can be placed anywhere in the hierarchy.

Creating Threads

In this approach, your class will implement the java.lang.Runnable interface. The Runnable interface consists of a single method, run(): your class must provide an implementation of it. This new run() method provides an entry point into your thread's execution. Your class is not a specialisation of the Thread, but you can obtain a reference to the thread by passing your Runnable object to a constructor of class Thread.

Here is an example program which creates two threads using the above ideas. This program performs the same tasks as the one you studied in the previous laboratory. You should be able to understand the details by yourself. However, here are some points to note :

Mutual Exclusion

Now we will try to study the different attempts for solving the mutual exclusion problem discussed in the lectures. We will study the first and second attempts in this lab. To remind you about these attempts, the first attempt uses a single variable called Turn to coordinate access to the critical section. The problem with this solution was that a process could starve if there is no contention. In other words, if process1 does not want to enter the critical section, process0 cannot enter the critical section and vice versa. I will explain below the details of the three files needed to program this solution.

MyObject.java. This is the base class which we will use in our programs.It has some useful methods like age() which determines the age of the current object of this or other inherited classes, getName() returns the name of the current object or thread, random() to return a random number and nap() to make the current thread sleep for a specified amount of time and also to report the duration of the sleep.

Attempts.java. In our solutions (or wrong solutions!), our processes (we will call them process but actually they are threads) execute the following loop. They first nap inside the non-critical section, then they express their desire to enter the critical section and once successful, they nap inside the critical section. They don't do anything useful since we are not interested in what they do inside their critical or non-critical sections. So we make them just sleep.

This file contains two classes: Process and MutualExclusion. We create threads by the method you have learnt today, ie by implementing the runnable interface.

The constructor Process takes several arguments which are easy to understand from their names, except the last one. The argument att is an object of the Attempt1 class. We will create different classes for different attempts for solving the mutual exclusion problem. We will explain this class in a moment. The variables napInsideCS and napOutsideCS are seeds for the random number generator which will determine the duration of sleep.

The methods insideCS and outsideCS simply make the thread sleep for sometime inside and outside the critical section. The run() method will provide the run() method required by the runnable interface. It simply calls the wantToEnterCS() and finishedInCS() methods of the Attempt1 class through the att object.

The MutualExclusion classcontains the main() method. It simply prints some messages, creates two threads (or processes if you like) by creating two instances of the Process class and passing the att object.

Attempt1.java. This is our first attempt almost directly from the book or the lecture notes. You should be able to follow the methods.

Tasks

Amitava Datta
March, 2000