Download COM337 Parallel Programming

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Java Threading, Mutex and
Synchronisation
Lecture 02
COMM86 Concurrent and Distributed Software Systems
University of
Sunderland
Program Threads
• A purely sequential (ie. non-concurrent) program
contains a single control path that it follows for
any given state of its data
Instruction 1
Instruction 3
Instruction 5
Begin
Instruction 0
Instruction 2
End
Instruction 4
• This path is referred to as a thread
University of
Sunderland
Program Threads
• A concurrent program will consists of any number
of concurrently operating threads
Instruction 3
Thread 1
Instruction 1
Instruction 5
Begin
Instruction 2
Instruction 0
Instruction 4
Thread 2
University of
Sunderland
End
Fork and Join
• When a single thread becomes a number of
additional concurrent threads it is referred to as a
fork
Thread 1
Instruction 1
Begin
Fork
Thread 2
University of
Sunderland
Instruction 0
Fork and Join
• When any number of concurrently running threads
form a single thread it is referred to as a Join
Thread 1
Instruction 5
Join
End
Instruction 4
Thread 2
University of
Sunderland
Synchronisation
• At some stage it is possible that a number of
concurrently running threads may need to
temporarily connect with each other (for example
to exchange data)
• This requires that the threads synchronise with
each other using some mechanism
University of
Sunderland
Java Thread Class
• Java provides a class that allows multi-threaded
operation of Java programs
• This class is called Thread and is part of the
java.lang package (so you do not need to import it)
• To support this, Java also includes the keyword
synchronized to effect mutual exclusion between
running threads
University of
Sunderland
Java Thread Mechanism
• To enable a Java class to operate as a thread do the
following:
– Write a class that extends the Thread class
– Provide a run( ) method in this class that will form the concurrent
operations of the class
– Call the start( ) method of the class once it has been instantiated
– The thread will terminate when the run( ) operation is completed
University of
Sunderland
An Example
• A program to create three independently running
threads that each output a set of numbers to the
console
University of
Sunderland
Example - Main Program Class
public class ThreadExample {
public static void main(String argv[]) {
ThreadExample theThreadExample = new ThreadExample( );
NumDisplayer[] theNumDisplayers = new NumDisplayer[3];
for(int i = 0; i < 3; i++) {
theNumDisplayers[i] = new NumDisplayer(i);
// Construct each NumDisplayer
theNumDisplayers[i].start( );
// Start each NumDisplayer thread (ie fork)
}
}
}
University of
Sunderland
Example - NumDisplayer Class
public class NumDisplayer extends Thread {
//Extends the java.lang.Thread class
int id;
public NumDisplayer(int anId) {
id = anId;
}
public void run( ) {
//Method that runs when start( ) method of the this class is called
for(int i = 0; i < 4; i++)
System.out.println("NumDisplayer [" + id + "] displays " + i);
}
}
University of
Sunderland
Example - Typical Output in MSDOS
c:> java ThreadExample
NumDisplayer [0] displays 0
NumDisplayer [0] displays 1
NumDisplayer [1] displays 0
NumDisplayer [2] displays 0
NumDisplayer [0] displays 2
NumDisplayer [1] displays 1
NumDisplayer [2] displays 1
NumDisplayer [0] displays 3
NumDisplayer [1] displays 2
NumDisplayer [2] displays 2
NumDisplayer [1] displays 3
NumDisplayer [2] displays 3
c:>
University of
Sunderland
• Note how the order in
which each thread
displays to the console is
interleaved
Synchronized Keyword
• Any Java class method can be declared as synchronized.
• Once synchronized, only one thread may enter that method at
anytime. Other threads wishing to do so block until the
orignal thread has completed running the synchronized
method.
• Hence you can use a synchronized method to ensure mutual
exclusive access to a class’s data
University of
Sunderland
Use of Synchronized
• To make a method synchronized, use the
synchronized keyword as a modifier for the
method, eg.
public synchronized void setData(int newData) {
data = newData;
}
This would allow a single thread to update the data
attribute of the class containing the setData() method at
any given moment
University of
Sunderland
Example 2 using synchronized
• Let us adapt the previous example so the
NumDisplayer objects take their value to display
from another thread based upon a class called
NumCounter
University of
Sunderland
Example 2 - Main Program Class
public class ThreadExample2 {
public static void main(String argv[]) {
ThreadExample2 theThreadExample = new ThreadExample2( );
NumCounter theNumCounter = new NumCounter( );
// Construct the NumCounter
theNumCounter.start( ); // Start the NumCounter
NumDisplayer2[] theNumDisplayers = new NumDisplayer2[3];
for(int i = 0; i < 3; i++) {
theNumDisplayers[i] = new NumDisplayer2(i, theNumCounter);
// Construct each NumDisplayer
theNumDisplayers[i].start( );
// Start each NumDisplayer
}
}
}
University of
Sunderland
Example 2 - NumCounter Class
public class NumCounter extends Thread {
int counter;
public NumCounter( ) {
counter = 0;
}
public synchronized int getNextNum( ) {
int currentNum = counter;
updateCounter( );
return currentNum;
}
public synchronized void updateCounter( ) {
counter++;
}
public void run( ) {
while(true) { //Go on and on ...
try {
Thread.sleep(100); // Let other threads operate, see later
}
catch(InterruptedException ie) { // Required because this exception is thrown by Thread.sleep( )
}
}
}
}
University of
Sunderland
Example – NumDisplayer2 Class
public class NumDisplayer2 extends Thread {
int id;
NumCounter theNumCounter; // Reference to the NumCounter
public NumDisplayer2(int anId, NumCounter aNumCounter) {
id = anId;
theNumCounter = aNumCounter;
}
public void run( ) {
for(int i = 0; i < 4; i++)
System.out.println("NumDisplayer [" + id + "] displays " +
theNumCounter.getNextNum( ));
}
}
University of
Sunderland
Example - Typical Output in MSDOS
c:> java ThreadExample2
NumDisplayer [0] displays 0
NumDisplayer [2] displays 1
NumDisplayer [1] displays 2
NumDisplayer [0] displays 3
NumDisplayer [1] displays 4
NumDisplayer [2] displays 5
NumDisplayer [0] displays 6
NumDisplayer [0] displays 7
NumDisplayer [2] displays 8
NumDisplayer [1] displays 9
NumDisplayer [1] displays 10
NumDisplayer [2] displays 11
c:>
University of
Sunderland
• Note how the order in
which each thread
displays to the console is
still interleaved and that
any thread can output any
of the possible numbers.
This is because we have
no control over the
sequence that the threads
operate in.
Thread Scheduling
• Notice that the previous example ensures mutual
exclusion, but what about scheduling?
• Java has a pre-emptive, priority-based thread
scheduler
• This means that if a higher priority thread needs
the CPU, a currently running lower priority thread
will be interrupted
University of
Sunderland
Fairness
• If all threads are of equal priority, then the
currently running thread will not be interrupted
and get exclusive use of the CPU.
• Thus we get an unfair scheduling of equal (or
lesser) priority threads
• Because of this, a thread must periodically
relinquish its use of the CPU in consideration of
other threads
University of
Sunderland
Thread.sleep( )
• To achieve this fairness in your Java programs, use the static
method Thread.sleep( ) to temporarily halt any long running
thread. This allows other threads access to the CPU.
• The method takes an integer value parameter that represents the
time (in milliseconds) the thread will halt. 100 is a good value
for this.
• Note: the Thread.sleep( ) method throws an
InterruptedException exception, so this must be caught
University of
Sunderland
Thread.sleep( ) Example
• The NumCounter class used previously introduced
a Thread.sleep( ) method call within its run( )
method.
(See the previous ThreadExample2 slides)
University of
Sunderland
Runnable Interface
• The previous examples have used the idea of
extension to enable a class to run as a thread. This
is problematic if the class must also extend
another class (such as JFrame)
• To overcome this, you can make the class
implement the Runnable interface, which allows
the class to be considered a thread
University of
Sunderland
Runnable Interface
• The Runnable Interface contains a single run( )
method that needs to be implemented (as per any
thread)
• Once a class implements the Runnable interface,
you can construct a thread for this class by passing
its class reference to the Thread class constructor
• Once the thread is started, the run( ) method of the
class will be called
University of
Sunderland
Runnable Interface Example
For example
public class ThreadExample3 implements Runnable {
Thread myThread;
// Reference to the thread this object will run upon
public ThreadExample3( ) {
myThread = new Thread(this);
// Construct the thread
myThread.start( );
// Start the thread, ie call the run( ) method of the ThreadExample3 class
}
public static void main(String argv[]) {
ThreadExample3 theThreadExample = new ThreadExample3;
}
public void run( ) {
while(true) {
// do something, and use Thread.sleep( ) to show consideration to other threads
}
}
}
University of
Sunderland
Thread Death
• Threads stop running under three circumstances:
1. The run( ) method completes
2. You call the stop( ) method of the thread (note this is
now a deprecated method so don’t use it!)
3. The whole process within which the thread is running is
terminated (i.e. when the Java VM completes)
• Since we have to control the lifespan of a thread through
the run( ) method, it is prudent to make this method come
under direct control also by using a completion flag
University of
Sunderland
Completion Flag
• Use a boolean variable to indicate whether the
thread has completed or not. Use this as the
condition for the while statement in the run( )
method, eg.
boolean completed = false;
public void run( ) {
while(!completed) {
….
}
}
University of
Sunderland
Is This All?
• No. The subject of Java threads is large and impossible to
do it justice in a single session. There will be more.
• You can find out more in the Java Tutorial and in most of
the Java texts
• For a near complete treatment of the subject, consult
“Java Threads”, Scott Oaks & Henry Wong, O’Reilly, 1997
“Concurrent Programming in Java”, Doug Lea, Addison Wesley, 2000
University of
Sunderland