Download lecture17 - McGill, University of

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

Prognostics wikipedia , lookup

Intelligent maintenance system wikipedia , lookup

Screw thread wikipedia , lookup

Transcript
308-203A
Introduction to Computing II
Lecture 17: Programming with
Threads in Java
Fall Session 2000
Multi-tasking
It is desireable to have a single computer run more
than one program at a time, e.g. running Netscape in
one window while editing a word-processor
document in another.
This goes by the names “multi-tasking” or “coursegrained parallelism.”
It’s managed autaomatically by all modern Operating
Systems (even Windows).
Threads = Multi-tasking
within a Program
Reasons we might want to do this:
- Efficiency: different activities can move
forward at their own speed
- Parallel processing: A computer may have
more than one processor to utilize, or more
than one computer on a network may participate
in a computation
- Natural for some programs, like…
Event-driven programming
Many programs must react in some way to events which
come from their environment.
Example 1 : Graphical User Interfaces respond
to mouse-clicks and keystrokes
Example 2 : Programs which run over the Internet
respond to receiving network packets
Example 3 : Robots respond to signals detected
by sensors
Event-driven programming
All these examples naturally suggest the use of threads.
Take the example of Netscape, with two windows
open.
Window A: Loading some page that’s taking forever
(waiting for an event from the network)
Window B: Has some on-line form to fill out
(waiting for events from the mouse /keyboard)
No fun if we have to wait for A to load to fill in B
A Bad Use of Threads
Ever notice that when Microsoft Word™ marks
spelling and grammatical errors, there is sometimes
a delay between the time you make a change and
the appearance of the green squiggly line to tell you
what Microsoft thinks of your command of basic
grammar?
That grammar checker is likely running in another
thread to avoid slowing down user input.
Creating threads in Java
Java provides a JDK class to let you create threads:
The recipe:
1) Extend a class from Thread
2) Override the method run() to do whatever
you want it to do
3) Create an object of your class and call a
pre-defined method called start()
An example
Create a thread class:
class helloWorldThread extends Thread {
run()
{
wait(5000);
// wait 5 seconds
System.out.println(“Hello world”);
}
}
An example
Use the thread class:
void main( String args [] )
{
helloWorldThread hwt = new helloWorldThread( );
System.out.println(“Starting the thread…”);
hwt.start();
System.out.println(“Done with the main method”);
}
An example
Output:
Starting the thread…
Done with the main method
Hello world
Immediate
Five seconds later
Race Conditions
Take two threads which both use the following code:
run( )
{
int j = 1;
while (true) System.out.println(“Count = “+ j);
}
What is the output?
Race Conditions
Answer: Almost anything!
Count = 1
Count = 2
Count = 3
Count = 1
Count = 2
Count = 4
Count = 3
Count = 4
Count = 5
// Thread “a”
// Thread “a”
// Thread “a”
// Thread “b”
// Thread “b”
// Thread “a”
// Thread “b”
// Thread “b”
// Thread “b”
Sharing of data
When two threads share data, things can become
problematic. Consider the following:
run( )
{
for (int i = 0; i < 10000; i++)
{
x = i;
// say x is static
if (x != i)
System.out.println(“Error!”);
}
}
Sharing of data
If you run two such threads , there will be lots of “errors”
Thread “a”
x = 1;
if (x != 1) “error”
x=2
Thread “b”
x = 1;
if (x != 1) “error”
if (x != 2) “error”
x=2
if (x != 2) “error”
Data Hazards
If threads could be run in an order where data
becomes corrupted, we say that there is a
“Data Hazard.”
This is almost universally the case when two threads
access data in an unprotected way.
Data Hazard - example
Consider two threads inserting elements at
the head of a linked-list:
Recall the code to do this is:
newNode.next = list.head ;
list
= newNode ;
Data Hazard - example
list
head
First node
newNode A
Thread A
newNode.next = list.head ;
newNode B
Thread B
newNode.next = list.head ;
list.head
= newNode ;
list.head
= newNode ;
Data Hazard - example
list
head
First node
newNode A
Thread A
newNode.next = list.head ;
newNode B
Thread B
newNode.next = list.head ;
list.head
= newNode ;
list.head
= newNode ;
Data Hazard - example
list
head
First node
newNode A
Thread A
newNode.next = list.head ;
newNode B
Thread B
newNode.next = list.head ;
list.head
= newNode ;
list.head
= newNode ;
Data Hazard - example
list
head
First node
newNode A
Thread A
newNode.next = list.head ;
newNode B
Thread B
newNode.next = list.head ;
list.head
= newNode ;
list.head
= newNode ;
Data Hazard - example
list
head
First node
newNode A
Thread A
newNode.next = list.head ;
newNode B
Thread B
newNode.next = list.head ;
list.head
= newNode ;
list.head
= newNode ;
Data Hazard - example
list
head
First node
newNode A
newNode B
The effect is that the newNode for thread A got
lost: it is not in the resulting list at all.
Mutual exclusion
A solution is to designate access to certain portions
of code, known as critical sections, as being mutually
exclusive.
For example, if only one thread at a time is allowed
to perform list operations like insertion, the problem
from the previous slides cannot occur.
Mutual exclusion in Java
“synchronized”
In Java, you can specify that certain methods are
synchronized, which tells the Java runtime environment
to guarantee mutually exclusive access to those methods.
For example, in Hashtable.java you find the actual
definitions of put and get are:
public synchronized Object get(Object key) …
public synchronized Object put(Object key, Object value)…
Any questions?