MVP1: Introduction to concurrency in JAVA
MVP1 2
Concurrency?
• A naive definition: More than one thing (activity) at a time.
• Independent activities: web download, number crunching, program editing, print.
• Dependent activities: file i/o, cpu execution.• Interleaved activities: users logged in on servers
(timesharing).• Parallel activities: sorting on multicomputeres.
MVP1 3
Concurrent programming?
Concurrencyoccurs at alllevels
MVP1 4
Concurrent programming?•We need ways to express the coordination of concurrencyat all system levels.• In this course, we will focus on the coordination of concurrency at the problem oriented language level in the Java language
MVP1 5
Granularity level?• We want to abstract away from specific architectures, i.e.
objects are the basic units for encapsulating concurrent
operations
MVP1 6
Two basic object invokation methods
• call-return (caller waits for callee)– Efficient– Callee is protected from
caller– Callee is a passive object
• start-stop (caller and calleecontinues)– Expensive calling sequence– Callee is not protected from
caller– Callee becomes an active
object (a thread)
start-stopcall-return
one thread two threads
MVP1 7
Typical execution platform
JVM’s
MVP1 8
JVM with threads
State 1 State 2 State 3 State 4
JVM
Four Thread States – each consistingof Program Counter & Object addressesFundamental problems:
Scheduling, Protection,Synchronization
MVP1 9
Java elements for concurrency(see also http://gee.cs.oswego.edu/dl/cpj/mechanics.html)
• Thread definition and initialization:– Class Thread and Interface Runnable
• Thread protection (lock) of methods:– Synchronized methods and blocks
• Thread synchronization:– A number of methods for thread manipulation when
methods are locked: wait, notify, notifyall, interrupt, timed wait
• Thread scheduling: sleep(msecs) function suspends caller thread for at least msecs milliseconds, yield releases CPU
• Thread state manipulation: interrupted, join
MVP1 10
Thread definition and intialization
• Two ways of thread definition:– Extend class Thread and override its run
method– Implement interface class Runnable (with a run
method), and supply it to a Thread constructor
• Object.start(): calls the run method in a separate thread (caller continues)
MVP1 11
Definition via Thread extensionclass Hello extends Thread {
public void run() {System.out.println("HelloWorld");
}}
public class Helloworld{public static void main(String args[]){
Hello t = new Hello();t.start();System.out.println("My first thread");
}}
MVP1 12
Definition via Runnable
class Second implements Runnable {public void run() {
System.out.println("HelloWorld");}
}
public class Secondworld{public static void main(String args[]){
Runnable runner = new Second();Thread t = new Thread(runner);t.start();System.out.println("My second thread");
}}
MVP1 13
Locking of shared methods
• Shared ressources are often represented by shared objects, e.g. shared printers
• The synchronized qualifier of methods in shared objects guarantees atomic method invocation
• At most one synchronized method per object can be active (including one static method per class)
MVP1 14
Locking example
class printer {…public synchronized printfile(String[] file);…}
Thread A:…p.printfile(f);…
Thread B:…p.printfile(g);…
- No fairness is guaranteed
MVP1 15
Thread manipulation in synchronized methods
• Each object has a waitset of threads waiting for reentering the object
• Wait: release lock and wait for lock• Notify: resume some thread from waitset• Notifyall: resume all threads from waitset• Wait(msecs): release lock and wait for it in msecs• Interrupt: notify, set state=interrupted and throw
exeption
MVP1 16
A first design: Water tank
• General development steps:– Object identification– Object models – possibly including protocols
and using standard design patterns – Behaviour analysis– Implementation
MVP1 17
Identification/Model
Invariants:-capacity is constant-0<=currentVolume<=
capacity-etc…
class WaterTank{final float capacity;float currentVolume = 0.0f;WaterTank overflow;
WaterTank(float cap){capacity = cap;...}
void addWater(float amount) throws OverflowException;void removeWater(float amount) throws UnderflowException;
}
MVP1 18
Patterns for invariant check•Water transfer is offered as an interface method:
interface Tank { float getCapacity();float getVolume();void transferWater(float amount)
throws OverflowException, UnderflowException;}
•We want to check the invariant before and after each transfer•Idea: Separate the transfer from the checks via wrappers – using proxy, subsclassing or command patterns
MVP1 19
Proxy pattern
• Basic idea: Provide a surrogate or placeholder for another object to control access to it
MVP1 20
Structure of proxy pattern
MVP1 21
Invariant check via proxy
class AdaptedTank implements Tank {
protected final Tank delegate;
public AdaptedTank(Tank t) { delegate = t; }
public float getCapacity() { return delegate.getCapacity(); }
public float getVolume() { return delegate.getVolume(); }
protected void checkVolumeInvariant() throwsAssertionError {
float v = getVolume();
float c = getCapacity();
if ( !(v >= 0.0 && v <= c) )
throw new AssertionError();
}
public synchronized void transferWater(float amount)
throws OverflowException, UnderflowException {
checkVolumeInvariant(); // before-check
try {
delegate.transferWater(amount);
}
// postpone rethrows until after-check
catch (OverflowException ex) { throw ex; }
catch (UnderflowException ex) { throw ex; }
finally {
checkVolumeInvariant(); // after-check
} }}
MVP1 22
Invariant check via subclassing
• Basic idea: Override the implementation, put into a context, and call method in superclass
MVP1 23
Subclassing implementationclass SubclassedTank extends TankImpl{
protected void checkVolumeInvariant() throws AssertionError {float v = getVolume();float c = getCapacity();if ( !(v >= 0.0 && v <= c) )throw new AssertionError();
}
public synchronized void transferWater(float amount) throws OverflowException, UnderflowException {
checkVolumeInvariant(); // before-check
try {super.transferWater(amount);
}
// postpone rethrows until after-checkcatch (OverflowException ex) { throw ex; }catch (UnderflowException ex) { throw ex; }
finally {checkVolumeInvariant(); // after-check
}}
MVP1 24
Check via command pattern
• Before ; <command> ; After• Basic idea: The command is sent to a
receiver, which processes the command in the before – after context
MVP1 25
Command pattern behaviour
MVP1 26
Pattern implementationinterface TankOp {
void op() throws OverflowException, UnderflowException;}class TankWithMethodAdapter {
// ...protected void checkVolumeInvariant() throws AssertionError
{ // ... identical to AdaptedTank version ...
}
protected void runWithinBeforeAfterChecks(TankOp cmd) throws OverflowException, UnderflowException {// identical to AdaptedTank.transferWater // except for inner call:
// ...try {cmd.op();
}finally {}
// ...}
protected void doTransferWater(float amount) throws OverflowException, UnderflowException { // ... implementation code ...
}
public synchronized void transferWater(final float amount) throws OverflowException, UnderflowException {
runWithinBeforeAfterChecks(new TankOp() {public void op() throws OverflowException, UnderflowException {doTransferWater(amount);
}});
}}