the zen of threads
DESCRIPTION
The Zen of Threads. When you can snatch the lock from the object, grasshopper, then you are ready to spawn the thread. Administrivia. P2 due Mon P3 assigned Mon Group project! Groups are up to you... Come ready w/ group choices on Mon 3-4 people per group (2 groups) - PowerPoint PPT PresentationTRANSCRIPT
The Zen of Threads
When you can snatch the lock from the object, grasshopper, then you are ready to spawn the thread...
Administrivia
P2 due Mon P3 assigned Mon
Group project! Groups are up to you... Come ready w/ group choices on Mon 3-4 people per group (2 groups) If you don’t pick, I will...
3 Types of Execution
Single, lone process doing all the work No problems with multiple-access Can be inconvenient/inefficient -- blocking,
single-user, etc. Multiple processes, possibly communicating
via sockets/files/FIFOs (traditional UNIX model) More efficient; no blocking, >1 user, etc. Hard to share data (all in terms of
messages) No synchronization problems
Threads Efficient; no blocking, >1 user, etc. Synchronization & data sharing tricky
The Weakness of One Process
public class mySwingApp { public static void main(String[] args) { mySwingApp app=new mySwingApp(args); app._init(); } private void _init() { JFrame jf=_buildGui(); jf.pack(); jf.setVisible(true); } // more GUI initialization private class _buttonHandler { public void actionPerformed(ActionEvent e) { if (e.getCommand().equals(“Connect to Web Site”)) { // look up web site; read data from it; store // data in memory } }
The Weakness of One Process
Problem 1: If any subroutine takes a long time, everything else (including UI) will have to wait for it (blocking)
Typical blocking operations I/O Network communication expensive computation (PuzzleMuncher)
Problem 2: no support for multiuser app/OS Pure batch mode Can’t have >1 person talk to DB/web
page/etc. at a time
The Multi-Process Model
Process (in UNIX sense) is a separate program, running in its own memory space, independent from every other program/process
Process has its own copy of code, its own PC, own stack & heap, etc.
Separation enforced by kernel & hardware All resource sharing passes through kernel
Sockets, files, pipes, FIFOs, etc. New proc created (in UNIX) w/ fork()
The Multi-Process Model
memory
proc 0
addi $0, 3bne $3, $4, 23nopmult $7, $19mflo $3sw $3, $11...
PC
text
stack
obj0
obj1
objN
heap
proc 2
addi $0, 3bne $3, $4, 23nopmult $7, $19mflo $3sw $3, $11...
PCtext
stack
obj1
objN
heap
proc 1
addi $0, 3bne $3, $4, 23nopmult $7, $19mflo $3sw $3, $11...
PC
text
stack
obj0
obj1
objN
heap
objN-1
Inter-Process Communication
memory
proc 0
addi $0, 3bne $3, $4, 23nopmult $7, $19mflo $3sw $3, $11...
PC
text
stack
obj0
obj1
objN
heap
proc 1
addi $0, 3bne $3, $4, 23nopmult $7, $19mflo $3sw $3, $11...
PC
text
stack
obj0
obj1
objN
heap
objN-1
pipe.write()
pipe.read()
pipe.read()
pipe.write()
The Multi-Thread Model
Threads run within a single process Each thread has its own
Program Counter Registers Stack (subroutine local vars)
All threads share Memory (all objects in common) Program code (same
methods/subroutines) No kernel/hardware separation (!) -- all
separation done by programmer (you!)
The Multi-Thread Model
memory
proc 0
addi $0, 3bne $3, $4, 23nopmult $7, $19mflo $3sw $3, $11...
text
obj0
obj1
objN
heap
stackPC
registers
thread 0stack
PC
registers
thread 1stack
PC
registers
thread 2
obj3
obj2
objN-1objN-3
objN-2
Inter-Thread Communication
memory
proc 0
addi $0, 3bne $3, $4, 23nopmult $7, $19mflo $3sw $3, $11...
text
obj0
obj1
objN
heap
stackPC
registers
thread 0stack
PC
registers
thread 1stack
PC
registers
thread 2
obj3
obj2
objN-1objN-3
objN-2
The Joy & Danger of Threads
All threads share same data Communication is trivial
All threads share same data Easy to stomp on another thread’s data!
Two threads can write to same location at same time, or one can write & one can read Can violate pre/post conditions of methods => Inconsistent data state
Have to synchronize accesses to ensure only one thread is meddling w/ important data at a time
Example Thread Data Corruptionprivate int[] _multArray[] = new int[128];private constructor() { for (int i=0;i<_multArray.length;++i) { _multArray[i]=i; }}private void _seedArray(int s) { for (int i=0;i<_multArray.length;++i) { _multArray[i]=i*s; }}private void _writeToFile() { _myFile.print(“_multArray=[ “); for (int i=0;i<_multArray.length;++i) { _myFile.print(_multArray[i] + “ “); } _myFile.println(“]”);}
Example Thread Data Corruption
_multArray
After constructor()
After _seedArray(2)
After _seedArray(3)
_multArray
_multArray
0 2 4 6 8 10 12 14 16 18 20 22 24
0 3 6 9 12 15 18 21 24 27 30 33 36
0 1 2 3 4 5 6 7 8 9 10 11 12
Example Thread Data Corruption
_multArray
After constructor()
Thread 0 calls _seedArray(2); Thread 1 calls _seedArray(3); Thread 2calls _writeToFile();
_multArray
0 1 2 3 4 5 6 7 8 9 10 11 12
0 1 2 3 4 5 6 7 8 9 10 11 12
Example Thread Data Corruption
_multArray
After constructor()
Thread 0 calls _seedArray(2); Thread 1 calls _seedArray(3); Thread 2calls _writeToFile();
_multArray
0 1 2 3 4 5 6 7 8 9 10 11 12
0 3 6 9 12 5 6 7 8 9 10 11 12
Thread 1 runs andgets to here...
Example Thread Data Corruption
_multArray
After constructor()
Thread 0 calls _seedArray(2); Thread 1 calls _seedArray(3); Thread 2calls _writeToFile();
_multArray
0 1 2 3 4 5 6 7 8 9 10 11 12
0 2 4 9 12 5 6 7 8 9 10 11 12
Thread 0 runs andgets to here...
Example Thread Data Corruption
_multArray
After constructor()
Thread 0 calls _seedArray(2); Thread 1 calls _seedArray(3); Thread 2calls _writeToFile();
_multArray
0 1 2 3 4 5 6 7 8 9 10 11 12
0 2 4 9 12 5 6 7 8 9 10 11 12
Thread 2 runs andgets to here...
_myFile: “_multArray=[ 0 2 4 9 12 5 6 “
Example Thread Data Corruption
_multArray
After constructor()
Thread 0 calls _seedArray(2); Thread 1 calls _seedArray(3); Thread 2calls _writeToFile();
_multArray
0 1 2 3 4 5 6 7 8 9 10 11 12
0 2 4 6 8 10 12 14 16 18 10 11 12
Thread 0 runs andgets to here...
_myFile: “_multArray=[ 0 2 4 9 12 5 6 “
Example Thread Data Corruption
_multArray
After constructor()
Thread 0 calls _seedArray(2); Thread 1 calls _seedArray(3); Thread 2calls _writeToFile();
_multArray
0 1 2 3 4 5 6 7 8 9 10 11 12
0 2 4 6 8 10 12 14 16 18 10 11 12
Thread 2 runs andgets to here...
_myFile: “_multArray=[ 0 2 4 9 12 5 6 14 16 18 10 11 “
Example Thread Data Corruption
_multArray
After constructor()
Thread 0 calls _seedArray(2); Thread 1 calls _seedArray(3); Thread 2calls _writeToFile();
_multArray
0 1 2 3 4 5 6 7 8 9 10 11 12
0 2 4 6 8 15 18 21 24 27 30 33 36
Thread 1 runs andgets to here...
_myFile: “_multArray=[ 0 2 4 9 12 5 6 14 16 18 10 11 “
Example Thread Data Corruption
_multArray
After constructor()
Thread 0 calls _seedArray(2); Thread 1 calls _seedArray(3); Thread 2calls _writeToFile();
_multArray
0 1 2 3 4 5 6 7 8 9 10 11 12
0 2 4 6 8 15 18 21 24 27 30 33 36
Thread 2 completes...
_myFile: “_multArray=[ 0 2 4 9 12 5 6 14 16 18 10 11 36]“
Synchronization
Problem is that you can’t control when/how long each thread runs
What you can do is ensure that the threads don’t work with the same data at the same time
Defn: Critical section -- one or more pieces of code that should not be invoked by >1 thread simultaneously
Defn: Mutual exclusion -- only one thread can be executing this block at a time
Defn: Lock -- data struct used to ensure mutual exclusion w/in critical sections
Synchronization in Java
Java provides synchronized keyword synchronized method: only one thread
can execute in this method at a time synchronized block: only one thread in
this block at a time Synchronization uses (invisible) lock
assoc. w/ object Normal method -- the invoking object Static method -- the global “class” obj Block -- the argument obj to that block
Execution of Synchronized Sections
Thread A enters synch section1. A checks for lock; points lock to self2. Enters code segment3. Completes code segment4. Releases lock (points it back to nobody)
Thread B enters synch at 3 B checks for lock; can’t get it; blocks When A completes 4, B can get lock B repeats 1-4 itself