Download EE2E1. JAVA Programming

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

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

Document related concepts
no text concepts found
Transcript
EE2E1. 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
interrupted by another thread wanting to run –
hence the try-catch clause


Each Counter object is created in the
actionPerformed() method of the button
attached to the outer frame (applet)

The thread is started by calling the start()
method

The number of threads started is counted
in the nthreads variable and the frame
colour selected accordingly
Thread states

A thread can exist in one of 4 states
 new
 The thread has just been created
 runnable
 The start() method has been called for
the thread and it is now ready to run
blocked
 Either the sleep() method has been called
 The thread has blocked on an I/O operation
 The thread has called the wait() method
 The thread tries to lock an object that is
locked by another thread
 dead
 Either the run() method for the thread has
completed or an uncaught exception has
terminated the run() method

sleep()
Done sleeping
blocked
wait()
notify()
new
start()
runnable
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


UNIX, LINUX


Each thread is given a timeslice after which
it is pre-empted by another thread of higher
or equal priority
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
P=5 P=5 P=3
Blocks
Blocks
Un-blocks
Blocked threads
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
 When a synchronised method is being
executed, the object is locked and no other
method can access the object until the method
completes
Unsynchronised threads
Thread 1
Thread 2
Pre-empt
Update
database
Pre-empt
Read
database
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
agent 1
Booking
agent 2
…..
Booking
agent n
Check availability
Reserve seat
Check
availability
Reserve seat
Check availability
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 preempted 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
Booking agent 1
Booking agent 2
check availability
pre-empted
check availability
re-schedule
book seat
book seat

2 main classes
 SeatBookings
 Contains the seat booking information (just a
simple array)
 Contains isAvailable() and bookSeat()
methods which access the seat booking
information
 BookingAgent
 Extends Thread and thus contains a run()
method
 Contains a reference to a SeatBookings
object which is thus a shared object between
all of the BookingAgent objects

The code is as follows (code to output to frames
has been omitted)
class SeatBookings
{
private int[] seats;
public SeatBookings(int[] s)
{
seats=s;
}
public boolean isAvailable(int seatno)
{
return (seats[seatno]==0);
}
public void bookSeat(int seatno)
{
if (isAvailable(seatno))
seats[seatno]++;
}
}
public boolean doubleBooked(int seatno)
{
return (seats[seatno]>1);
}
class BookingAgent extends Thread
{
private SeatBookings sb;
// shared object
public BookingAgent(SeatBookings s)
{
sb=s;
}
public void run()
{
do
{
int seatno=(int)(Math.random()*20000);
sb.bookSeat(seatno);
if (sb.doubleBooked(seatno))
// generate a warning dialog
}
}
} while (true);

We can synchronise the threads by tagging
the SeatBookings.bookSeat() method as
synchronized
 The SeatBookings object is then locked
by the thread which has current access
Booking
agent 1
locked
Booking
agent 2
locked out
SeatBookings object
Synchronised threads
Booking agent 1
Booking agent 2
check availability
book seat
check availability
book seat
check availability
book seat

Simple change to code
class SeatBookings
{
.
.
}

public synchronized void bookSeat(int seatno)
{
…
}
.
.
No double booking then takes place
http://www.eee.bham.ac.uk/spannm/Java%20
Stuff/SeatBooking%20SynchApplet/SeatBook
ingSynchApplet.html
The Runnable interface


So far, to develop classes which support multithreading we have extended the Thread class and
overwritten the run() method
This causes problems if the class is already
extended from another class
 Java doesn’t support multiple inheritance
SuperClass
MyClass
Thread

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 :
MyClass myObject=new Myclass();
Thread t=new Thread(myObject);
t.start();

The call to Thread(Runnable r) creates a
thread
 Calling Thread.start() then automatically
calls the run() method of the Runnable
object
Example – a counter applet


We will create an applet which has 2 buttons
 Start Count
 Reset Count
The thread to do the counting must run in a
separated thread to the one which handles button
presses
 Swing programs create an event dispatch thread
which handles all the events generated by the
program (including window events for
repainting graphics)
Main thread
Event dispatch
thread
Counting
thread
Construct applet
container
show container
exits
Start button
pressed
Start
counting …
Reset count
Reset button
pressed

The following applet doesn’t use a separate thread
to do the counting
 Button press events or repainting events can’t
be handled once counting begins
 http://www.eee.bham.ac.uk/spannm/Java%2
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!