Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
JAVA Programming
Lecture 8
Multi-threading
Contents
Introduction
Creating a thread the Thread class
Starting and running threads
Thread states
Thread priorities and scheduling
Thread synchronisation
The Runnable interface
Introduction
You are used to computers (operating systems)
being multi-tasking
You can browse the web whilst editing your
Java programs!
Multi-tasking refers to an operating system running
several processes concurrently
Each process has its own completely
independent data
Multi-tasking is difficult to incorporate in
application programs requiring system
programming primitives
Java is the only commonly used programming
language that enables concurrency to be
implemented within application programs
Multi-threading
An application program can be written as a set of
threads which run concurrently (in parallel)
A thread is different from a process in that threads
share the same data
Switching between threads involves much less
overhead than switching between programs
Sharing data can lead to programming
complications (for example in reading/writing
databases)
Creating threads the Thread class
To run a piece of code in a separate thread it is
placed in the run() method of a class which
extends Thread
class ThreadApp extends Thread
{
public void run()
{
// This code runs in a new thread
}
public static void main(String args[])
{
ThreadApp m=new ThreadApp();
m.start();
}
}
The Thread class has a start() method
which automatically calls run()
main() thread
new thread created
new thread
Example
The following simple application creates
separate threads to update a count within a
window
http://www.eee.bham.ac.uk/spannm/Java%2
0Stuff/ThreadTestApplet/ThreadTestApplet
.html
Main thread
Create counter
thread
Create counter
thread
..
Class Counter stores the current count and a
frame to display the text
It has a a run() method which simply slowly
counts upwards within a separate thread
class Counter extends Thread
{
public Counter(LabelFrame frame)
{}
public void run()
{..}
private int count=0;
private LabelFrame labelFrame;
}
public void run()
{
try
{
do
{
count++;
labelFrame.getPanel().setCount(count);
sleep(10);
labelFrame.repaint();
} while (true);
}
catch(InterruptedException e){}
}
public class ThreadTestFrame extends JFrame
{
private int nthreads=0;
public ThreadTestFrame()
{
Container contentPane=getContentPane();
JPanel p=new JPanel();
addButton(p,"Start Count",
new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
// Select frame colour
Counter c=new Counter(new LabelFrame(color));
c.start();
nthreads++;
}
});
contentPane.add(p,"South");
}
public void addButton(Container c, String title, ActionListener a)
{ // Add button to a panel }
}
The sleep(int t) method is a static method of
Thread which puts the currently running thread to
sleep for t milliseconds
This allows other counters running in separate
threads to resume counting
sleep() throws an exception when the thread is
runnable
wait()
notify()
new runnable
start()
block on I/O
I/O complete
run() method exits
dead
Thread priorities and scheduling
Every thread has a priority which can be increased
or decreased by calling the setPriority() method
Thread.MIN_PRIORITY is the minimum
priority (defined 1)
Thread.MAX_PRIORITY is the maximum
priority (defined as 10)
When a thread is created, it is given a priority
of 5 defined as Thread.NORM_PRIORITY
Thread scheduling
Differs depending on the operating system
Windows
Each thread is given a timeslice after which
it is pre-empted by another thread of higher
or equal priority
UNIX, LINUX
A thread can only be pre-empted by a thread
of higher priority. If one is not available, the
thread runs to completion
In both cases, lower priority threads can only run
if all higher priority threads are blocked
Runnable threads Blocked threads
Blocks
Blocks
Un-blocks
Thread synchronisation
Threads need to share access to objects and may
update shared objects
For example multiple threads may access a
database for an online flight booking system
One thread may be updating a database entry
whilst another is reading it may lead to problems
We can synchronise threads so that they must
complete their action before another thread is
scheduled
We do this by tagging methods as synchronized
Thread 1 Thread 2
Pre-empt
Update Read
database database
Pre-empt
Synchronised threads
Thread 1 Thread 2
Update
database
Read
database
Example An online seat
reservation system
Seats for a concert can be reserved through
booking agents
The processing for each booking agent runs in a
separate thread possibly on a different processor
Each booking transaction must check seat
availability before reserving the seat
Booking Booking
agent 2
.. Booking
agent n
agent 1
Check availability
Reserve seat
Check
availability Check availability
Reserve seat Reserve seat
Seat reservation
database
Pseudo-code for booking a seat
if seat n is available
book seat n;
Code not atomic
For an unsynchronised thread it can be pre-
empted by another thread after the if statement
The thread might think the seat is available but
it then might be booked by the pre-empting
thread
The seat will be double booked
http://www.eee.bham.ac.uk/spannm/Java%20Stuff
/SeatBookingApplet/SeatBookingApplet.html
Unsynchronised threads
check availability
Booking Booking
agent 1 agent 2
SeatBookings object
Synchronised threads
check availability
book seat
check availability
book seat
check availability
book seat
Simple change to code
class SeatBookings
{
.
.
public synchronized void bookSeat(int seatno)
{
}
.
.
}
SuperClass Thread
MyClass
This is generally a problem if we want outer
containers (JFrame or JApplet) objects to support
multi-threading
The simple solution is to make our class
implement the Runnable interface
It would then need to implement a run()
method in the usual way
class myClass extends superClass implements Runnable
{
public void run() {}
}
A thread is created and MyClass.run()
started as follows :
Reset Count
Construct applet
container
show container
0Stuff/CounterApplet/CounterApplet.html
The following applet generates a separate
thread for the counter
http://www.eee.bham.ac.uk/spannm/Java%2
0Stuff/RunnableTestApplet/RunnableTestAp
plet.html
public class RunnableTestApplet extends JApplet implements
Runnable
{
public void init()
{
// Generate outer container
addButton(p,"Start Count",
new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
startCount();
}
});
addButton(p,"Reset Count",
new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
resetCount();
}
});
// Add buttons to container
}
public void startCount()
{
runner=new Thread(this);
runner.start();
}
public void resetCount()
{
runner.interrupt();
count=0;
// repaint frame
}
public void run()
{
while (!Thread.interrupted())
{
count++;
// repaint frame
}
}
private Thread runner;
} // end of class RunnableTestApplet
And finally..
Multi-threading is complex
Make sure you understand the code for the first example
we looked at
Run the applet from my web site and scrutinize the code
Multi-threading is the basis of many applications and, as
we have seen, particularly crucial in graphical/event driven
programming
We have only scratched the surface. For an excellent and
thorough description of threading see
www.albahari.com/threading
In the last lab exercise, you will have the opportunity to
write a multi-threading server for a network-based game!