308-203AIntroduction to Computing II
Lecture 17: Programming with Threads in Java
Fall Session 2000
Multi-taskingIt is desireable to have a single computer run morethan one program at a time, e.g. running Netscape inone window while editing a word-processordocument in another.
This goes by the names “multi-tasking” or “course-grained parallelism.”
It’s managed autaomatically by all modern OperatingSystems (even Windows).
Threads = Multi-taskingwithin 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 whichcome from their environment.
Example 1 : Graphical User Interfaces respondto mouse-clicks and keystrokes
Example 2 : Programs which run over the Internetrespond 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 windowsopen.
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™ marksspelling and grammatical errors, there is sometimesa delay between the time you make a change andthe appearance of the green squiggly line to tell youwhat Microsoft thinks of your command of basicgrammar?
That grammar checker is likely running in anotherthread 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 Thread2) Override the method run() to do whatever
you want it to do3) Create an object of your class and call a pre-defined method called start()
An example
class helloWorldThread extends Thread {
run(){ wait(5000); // wait 5 seconds
System.out.println(“Hello world”);}
}
Create a thread class:
An example
void main( String args [] ){ helloWorldThread hwt = new helloWorldThread( );
System.out.println(“Starting the thread…”);
hwt.start();
System.out.println(“Done with the main method”);}
Use the thread class:
An example
Starting the thread…Done with the main methodHello world
Output:
Five seconds later
Immediate
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 ConditionsAnswer: Almost anything!
Count = 1 // Thread “a”Count = 2 // Thread “a”Count = 3 // Thread “a”Count = 1 // Thread “b”Count = 2 // Thread “b”Count = 4 // Thread “a”Count = 3 // Thread “b”Count = 4 // Thread “b”Count = 5 // Thread “b”
Sharing of dataWhen two threads share data, things can becomeproblematic. Consider the following:
run( ){ for (int i = 0; i < 10000; i++) {
x = i; // say x is staticif (x != i)
System.out.println(“Error!”); }}
Sharing of dataIf you run two such threads , there will be lots of “errors”
Thread “a”x = 1;if (x != 1) “error”x = 2
if (x != 2) “error”
Thread “b”
x = 1;if (x != 1) “error”
x = 2if (x != 2) “error”
Data Hazards
If threads could be run in an order where databecomes corrupted, we say that there is a“Data Hazard.”
This is almost universally the case when two threadsaccess data in an unprotected way.
Data Hazard - example
Consider two threads inserting elements atthe head of a linked-list:
Recall the code to do this is:
newNode.next = list.head ;list = newNode ;
Data Hazard - example
Thread AnewNode.next = list.head ;
list.head = newNode ;
Thread B
newNode.next = list.head ;
list.head = newNode ;
head
list
newNode A newNode B
First node
Data Hazard - example
Thread AnewNode.next = list.head ;
list.head = newNode ;
Thread B
newNode.next = list.head ;
list.head = newNode ;
head
list
newNode A newNode B
First node
Data Hazard - example
Thread AnewNode.next = list.head ;
list.head = newNode ;
Thread B
newNode.next = list.head ;
list.head = newNode ;
head
list
newNode A newNode B
First node
Data Hazard - example
Thread AnewNode.next = list.head ;
list.head = newNode ;
Thread B
newNode.next = list.head ;
list.head = newNode ;
head
list
newNode A newNode B
First node
Data Hazard - example
Thread AnewNode.next = list.head ;
list.head = newNode ;
Thread B
newNode.next = list.head ;
list.head = newNode ;
head
list
newNode A newNode B
First node
Data Hazard - example
head
list
newNode A newNode B
First node
The effect is that the newNode for thread A gotlost: it is not in the resulting list at all.
Mutual exclusion
A solution is to designate access to certain portionsof code, known as critical sections, as being mutuallyexclusive.
For example, if only one thread at a time is allowedto perform list operations like insertion, the problemfrom the previous slides cannot occur.
Mutual exclusion in Java“synchronized”
In Java, you can specify that certain methods aresynchronized, which tells the Java runtime environmentto guarantee mutually exclusive access to those methods.
For example, in Hashtable.java you find the actualdefinitions of put and get are:
public synchronized Object get(Object key) … public synchronized Object put(Object key, Object value)…
Any questions?